I'm building a .NET 3.5 application and have the need to evaluate JS code on the server - basically a user provided rule set that can work within a browser or on the server. Managed JS is not an option, because the JS code would be provided at runtime. Aptana's Jaxer is also not an option. So I was looking into using a build of the V8 engine within my app.
I built the source successfully into a DLL, but that DLL is not not a managed library and is not COM either. V8 is just plain C++.
Any ideas as to how to interop with this type of DLL in C#? Also, I'm open to other suggestions for SpiderMonkey or another JS engine.
Thanks in advance.
UPDATE:
I was able to use Ryan's solution. I just updated the references to the build for the latest from trunk. It worked great. Thanks Ryan.
I realize that this may not be an exact answer to your question, but I figured I would put my 2 cents worth in as I doubt to many people have tried this.
I got it to work by created a managed wrapper using mixed mode C++. There are other ways to do it, but I was going to attempt to make a full wrapper that could be used from any .NET language.
Getting the lib to compile in such a way that it could be included in a mixed mode project was a little bit of a challenge. I had to modify the runtime library (in the SConstruct file) used to /MD and /MDd so that it would be compatible with the /clr switch.
So far I have only simple scripts running as I have not implemented callbacks, custom methods, objects and such.
Here is a quick sample of what the usage looks like for one of my test apps:
V8DotNet.Shell shell = new V8DotNet.Shell();
shell.ExecuteScript(@"print('V8 version is: ' + version());");
It runs more complicated scripts like a base64 encoder fine as well. But for now I can only add custom items from the c++ side.
I am willing to provide more information + code if anyone is interested as I may not ever pick this project back up. But, I'm afraid it way to much code to go into a post here so we would have to find some other medium like google code or codePlex.
Edit:
OK, I've uploaded the code. I do have to put a disclaimer on this: The project is very early and I am an amateur at C++ at best so don't get your hopes up too much. Also, this project was created/done just after chrome was released so the version of v8 included may be old.
That said, here it is: http://ryanscook.com/Files/V8-DotNet.zip (21.5 MB)
In the package you'll find the following items of interest:
V8Net-Library\V8.Net\V8.Net.sln - This
is the solution that has the managed
C++ wrapper proj and a C# console app
for testing.
Dependencies\V8 - This is my V8 code
that I used to build the V8 lib.
Hope it helps!
You can try Javascript .NET:
http://javascriptdotnet.codeplex.com/
It lets you create a V8 context from .NET and register CLI objects in it so you can manipulate them and call members from the Javascript code. It compiles the Javascript at runtime.
Check it out.
Check out v8sharp. It supports executing JS inside of a .NET application. It also allows you to register .NET types with the v8 engine so that your JS code can interact with your .NET code. I am in the process of adding support for hooking function/delegate support.
Microsoft are building a real javascript - not "JScript" - runtime (along with IronPython, IronRuby, and VB10) on the CLR using the DLR, but I can't find any downloads or content for it. Perhaps this will arrive with C# 4?
From what I hear compiling it with IJW (Managed C++) should just work - but I may be really wrong, I have never touch MC++.
I guess gatapia has replaced js.net with jish
You can try V8.NET as well.
http://v8dotnet.codeplex.com/
It allows you to easily integrate code with V8 at a lower level than many other wrappers.
Necromancing.
As per 2018 and .NET Core 2.0+
you can use vroomjs-core
Execute some 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
}
}
Create and return a Javascript object, then call a method on it:
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 ...?"));
}
}
Access properties and call methods on CLR objects from Javascript:
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!):')");
}
}