This project has moved and is read-only. For the latest updates, please go here.

[SOLVED] Delegate Input Types + Returning Function Delegates

Sep 18, 2013 at 9:27 PM
Edited Sep 18, 2013 at 10:13 PM

My goal is to return an object with a funky constructor:

SomeObject(SomeClass first, string[] second, SomeDelegate third(string, string, string))

To get there, I first need to create a function in Javascript that matches SomeDelegate and return it to C#. Here's a simplified version:

x = function(a, b) {
return a + b;

If I evaulate this, I get an instance of V8ScriptItem. I can then do this:

V8ScriptItem delegate;
using (var e = new V8ScriptEngine()) { delegate = v.Evaulate(script); }
delegate.Invoke(new string[] { "a", "b" }); // returns "12"

There are a couple of problems with this.
  1. The input parameters can only be strings. Anything else (eg. ints) gives me a type conversion failure. I think passing in objects will cause a problem too.
  2. The return value is a V8ScriptItem instance. It's not a SomeDelegate instance. This makes my code use a bunch of "dynamic" on the C# side, which I want to avoid.
  3. V8ScriptEngine is an internal type. Even if I return it as an instance of "object", any attempt to call Invoke(...) gives me an exception: "TypeError: Method or property not found."
I have a roughly equivalent script working with IronRuby where I can instantiate some stuff in Ruby and get back a strongly-typed delegate and object on the C# side. Is it possible to get this working somehow?
Sep 18, 2013 at 10:34 PM
Greetings ashes999!

V8ScriptItem is an internal class; how are you using it? :-)

Anyway, if we understand correctly, you can do this easily in ClearScript. Suppose you have a delegate like this:
public delegate int SomeDelegate(int foo, string bar);
You can bind a script function (and then execute it from C#) like this:
using (var e = new V8ScriptEngine())
    e.AddHostType("SomeDelegate", typeof(SomeDelegate));
    var d = (SomeDelegate)e.Evaluate(
        "new SomeDelegate(function (foo, bar) { return foo + bar.length; })");
    Console.WriteLine(d(5, "blah")); // prints "9"
Sep 19, 2013 at 3:40 AM
@ClearScript it seems to be working. That's oustanding.


As for V8ScriptItem, I have my scripting stuff isolated in a single class; there, I can execute the script, and if the return type is dynamic, I can see that it's really an instance of V8ScriptItem which I can call Invoke on. But it doesn't work outside of the scope of a live engine instance.

So things are working now! Thanks for such a quick reply :)