我正在构建一个.NET 3.5应用程序,并且需要在服务器上评估JS代码 - 基本上是用户提供的规则集,可以在浏览器或服务器上运行。托管JS不是一个选项,因为JS代码将在运行时提供。 Aptana的Jaxer也不是一个选择。所以我正在考虑在我的应用程序中使用V8引擎的构建。
我将源成功构建到DLL中,但该DLL不是托管库,也不是COM。 V8只是简单的C ++。
如何在C#中与这种类型的DLL互操作?另外,我对SpiderMonkey或其他JS引擎的其他建议持开放态度。
提前致谢。
更新
我能够使用Ryan的解决方案。我刚刚更新了对trunk的最新版本的引用。它运作得很好。谢谢Ryan。
答案 0 :(得分:33)
我意识到这可能不是你问题的准确答案,但我想我会把我的2美分价值,因为我怀疑很多人都试过这个。
我通过使用混合模式C ++创建了一个托管包装器来实现它。还有其他方法可以做到,但我打算尝试制作一个可以在任何.NET语言中使用的完整包装器。
让lib以一种可以包含在混合模式项目中的方式进行编译是一个有点挑战。我不得不修改用于/ MD和/ MDd的运行时库(在SConstruct文件中),以便它与/ clr开关兼容。
到目前为止,我只运行了简单的脚本,因为我没有实现回调,自定义方法,对象等。
以下是我的某个测试应用的使用情况的快速示例:
V8DotNet.Shell shell = new V8DotNet.Shell();
shell.ExecuteScript(@"print('V8 version is: ' + version());");
它运行更复杂的脚本,如base64编码器也很好。但是现在我只能从c ++端添加自定义项目。
如果有人感兴趣,我愿意提供更多信息+代码,因为我可能永远不会选择这个项目。但是,我担心要在这里发布一些帖子的代码很多,所以我们必须找到其他一些媒体,如谷歌代码或codePlex。
修改强>
好的,我上传了代码。我必须对此进行免责声明:该项目很早,我最好是C ++的业余爱好者,所以不要过多地抱你的希望。此外,这个项目是在Chrome发布后创建/完成的,所以包含的v8版本可能已经过时了。
那就是说:http://ryanscook.com/Files/V8-DotNet.zip(21.5 MB)
在包装中,您会找到以下感兴趣的项目:
V8Net-Library \ V8.Net \ V8.Net.sln - 这个 是有管理的解决方案 C ++包装器项目和一个C#控制台应用程序 用于测试。
依赖关系\ V8 - 这是我的V8代码 我曾经用来构建V8库。
希望它有所帮助!
答案 1 :(得分:18)
您可以尝试使用Javascript .NET:
http://javascriptdotnet.codeplex.com/
它允许您从.NET创建V8上下文并在其中注册CLI对象,以便您可以操作它们并从Javascript代码中调用成员。它在运行时编译Javascript。
检查出来。
答案 2 :(得分:13)
结帐v8sharp。它支持在.NET应用程序中执行JS。它还允许您使用v8引擎注册.NET类型,以便您的JS代码可以与您的.NET代码进行交互。我正在添加对挂钩函数/委托支持的支持。
答案 3 :(得分:1)
使用DLR的CLR上的Microsoft are building a real javascript - not "JScript" - runtime(以及IronPython,IronRuby和VB10),但我找不到任何下载或内容。也许这将与C#4一起到达?
答案 4 :(得分:0)
从我听到的用IJW(托管C ++)编译它应该只是工作 - 但我可能真的错了,我从来没有接触过MC ++。
答案 5 :(得分:0)
答案 6 :(得分:0)
您也可以尝试使用V8.NET。
https://www.nuget.org/packages/V8.Net/
它允许您轻松地将代码与V8集成在比许多其他包装器更低的级别。它还支持.Net 4.6.1+和.Net Standard 2.0+(.Net Core)。
答案 7 :(得分:0)
不断创新。
根据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!):')");
}
}
答案 8 :(得分:0)
由于这个问题是在不久前发布的,所以我想我要进行一些更新。
Microsoft已经制作了ClearScript脚本引擎,该引擎支持V8,JScript和VBScript。
您可以轻松添加C#类型(例如控制台),并在脚本内使用它。 添加WPF按钮类型并创建一个也不是问题。 github中有一些很棒的例子,所以我建议任何阅读此书的人快速浏览一下。