.NET アプリから Google の V8 エンジンを参照する
-
21-08-2019 - |
質問
.NET 3.5 アプリケーションを構築していますが、サーバー上で JS コードを評価する必要があります。基本的には、ブラウザー内またはサーバー上で機能するユーザー提供のルール セットです。JS コードは実行時に提供されるため、マネージド JS はオプションではありません。Aptana の Jaxer もオプションではありません。そこで、アプリ内で V8 エンジンのビルドを使用することを検討していました。
ソースを DLL に正常にビルドしましたが、その DLL はマネージド ライブラリではなく、COM でもありません。V8 は単なる C++ です。
C# でこのタイプの DLL と相互運用する方法について何かアイデアはありますか?また、SpiderMonkey や別の JS エンジンに関する他の提案も歓迎します。
前もって感謝します。
アップデート:
Ryan のソリューションを使用することができました。トランクから最新のビルドへの参照を更新しました。とてもうまくいきました。ありがとうライアン。
解決
これがあなたの質問に対する正確な答えではないかもしれないことは承知していますが、多くの人がこれを試したことがあるとは思えないので、私は 2 セント相当を投じることにしました。
混合モード C++ を使用してマネージ ラッパーを作成することで、それが機能するようになりました。他にも方法はありますが、私は任意の .NET 言語から使用できる完全なラッパーを作成しようとしました。
混合モードのプロジェクトに含められるようにライブラリをコンパイルするのは、少し困難でした。/MD および /MDd に使用されるランタイム ライブラリ (SConstruct ファイル内) を、/clr スイッチと互換性があるように変更する必要がありました。
これまでのところ、コールバック、カスタム メソッド、オブジェクトなどを実装していないため、単純なスクリプトのみを実行しています。
以下は、テスト アプリの 1 つの使用状況の簡単なサンプルです。
V8DotNet.Shell shell = new V8DotNet.Shell();
shell.ExecuteScript(@"print('V8 version is: ' + version());");
Base64 エンコーダなどのより複雑なスクリプトも問題なく実行できます。ただし、現時点では C++ 側からカスタム項目を追加することしかできません。
このプロジェクトを再び取り上げることはできないかもしれないので、興味がある人がいたら、喜んで詳細情報とコードを提供します。ただし、ここに投稿するにはコードが多すぎるので、Google コードや codePlex などの他の媒体を見つける必要があると思います。
編集:
OK、コードをアップロードしました。これについては免責事項を付けておかなければなりません: このプロジェクトは非常に初期のもので、私は C++ に関してはせいぜい素人なので、あまり期待しないでください。また、このプロジェクトは chrome がリリースされた直後に作成/実行されたため、含まれている v8 のバージョンは古い可能性があります。
つまり、次のとおりです。 http://ryanscook.com/Files/V8-DotNet.zip (21.5MB)
パッケージには次の興味深いアイテムが含まれています。
V8Net-Library\V8.Net\V8.Net.sln - これは、マネージドC ++ラッパーProJとテスト用のC#コンソールアプリを備えたソリューションです。
依存関係\V8 - これは、V8 LIBの構築に使用したV8コードです。
それが役に立てば幸い!
他のヒント
Javascript .NET を試すことができます。
http://javascriptdotnet.codeplex.com/
これにより、.NET から V8 コンテキストを作成し、そこに CLI オブジェクトを登録して、それらを操作したり、JavaScript コードからメンバーを呼び出したりできるようになります。実行時に JavaScript をコンパイルします。
それをチェックしてください。
チェックアウト v8シャープ. 。.NET アプリケーション内での JS の実行をサポートします。また、.NET 型を v8 エンジンに登録して、JS コードが .NET コードと対話できるようにすることもできます。フック関数/デリゲートのサポートの追加を進めているところです。
マイクロソフト 「JScript」ではなく、実際の JavaScript ランタイムを構築しています (IronPython、IronRuby、および VB10 とともに) DLR を使用して CLR 上で実行できますが、ダウンロードやコンテンツが見つかりません。おそらくこれは C# 4 で提供されるでしょうか?
聞くところによると、IJW (マネージド C++) でコンパイルするとうまくいくはずですが、私は本当に間違っているかもしれません。私は MC++ に触れたことはありません。
ネクロマンシング。
2018 および .NET Core 2.0 以降による
使用できます vroomjs-core
いくつかの Javascript を実行します。
using (var engine = new JsEngine())
{
using (var context = engine.CreateContext())
{
var x = (double)context.Execute("3.14159+2.71828");
Console.WriteLine(x); // prints 5.85987
}
}
JavaScript オブジェクトを作成して返し、そのオブジェクトに対してメソッドを呼び出します。
using (JsEngine js = new JsEngine(4, 32))
{
using (JsContext context = js.CreateContext())
{
// Create a global variable on the JS side.
context.Execute("var x = {'answer':42, 'tellme':function (x) { return x+' '+this.answer; }}");
// Get it and use "dynamic" to tell the compiler to use runtime binding.
dynamic x = context.GetVariable("x");
// Call the method and print the result. This will print:
// "What is the answer to ...? 42"
Console.WriteLine(x.tellme("What is the answer to ...?"));
}
}
Javascript から CLR オブジェクトのプロパティにアクセスし、メソッドを呼び出します。
class Test
{
public int Value { get; set; }
public void PrintValue(string msg)
{
Console.WriteLine(msg+" "+Value);
}
}
using (JsEngine js = new JsEngine(4, 32))
{
using (JsContext context = js.CreateContext())
{
context.SetVariable("m", new Test());
// Sets the property from Javascript.
context.Execute("m.Value = 42");
// Call a method on the CLR object from Javascript. This prints:
// "And the answer is (again!): 42"
context.Execute("m.PrintValue('And the answer is (again!):')");
}
}
V8.NET も試すことができます。
https://www.nuget.org/packages/V8.Net/
これにより、他の多くのラッパーよりも低いレベルでコードを V8 と簡単に統合できます。.Net 4.6.1+ および .Net Standard 2.0+ (.Net Core) もサポートします。