Problem dealing with arrays in VBScript

Mar 17, 2014 at 9:23 AM
Hi,
I have following simple code. It works fine with MSScriptControl, but using VBScriptEngine it doesen't work:
    private void btnExecuteScript_Click(object sender, EventArgs e)
    {
        try
        {
            using (ScriptEngine engine = new VBScriptEngine())
            {
                object[] array = new object[] { 1, 2, 3 };
                engine.AddHostObject("arr", array);
                var value = (string)engine.Evaluate("arr(1) = 1");  
                MessageBox.Show(value.ToString());
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
Error message is: "Object does not support the requested invocation operation"

I'm new to clearscript. What i#m doing wrong?

Best regards
nbgedo
Coordinator
Mar 17, 2014 at 4:00 PM
Hello nbgedo!

ClearScript does not convert host arrays to VBScript arrays. To retrieve a value from a host array, you have to use a host method. For example:
engine.Execute(@"
    x = arr.GetValue(0)
    call arr.SetValue(x, 1)
");
Cheers!
Sep 4, 2014 at 4:01 PM
I've come across this same issue. Would it be possible to implement support for this? I'm trying to migrate away from the MS Script Control (used as an ActiveX control in .NET) to ClearScript using VBScriptEngine, and everything is working perfectly apart from this one issue. There are already customer scripts out there that expect to be able to receive arrays in VBScript from the host application, so we need to be able to preserve that behaviour.

Basically I would like to be able to call:

object[] array = new object[] { ...... };
engine.Script.MyFunction(array);

and have "array" pass through to VBScript properly.

I'm also having problems trying to access a C# function from VBScript that returns data through an array. I can do the following in MSScriptControl, but not with ClearScript:

Dim x
Dim y
funcs.GetArray x, y

public void getLogData(ref dynamic x, ref object y)
{
x = new int[5];
y = 10;
}

It's the "ref" that ClearScript seems not to like. Is this a particularly difficult problem to solve?

Thanks very much for the great work on ClearScript, it's a fantastic bit of software!
Coordinator
Sep 4, 2014 at 9:16 PM
Hi orudge,

Thanks for your kind words!

When it comes to running existing VBScript code that relies on certain features of classic ActiveX embedding, ClearScript is definitely missing a few things. It was originally designed to make it easy to add scripts to existing hosts, not vice versa :)

Nevertheless, native array marshaling is something we're investigating as a global option, similar to WindowsScriptEngineFlags.MarshalDecimalAsCurrency. Do you think that would suffice?

The second part of your question deals with methods that have output parameters. ClearScript provides a way to invoke such methods from script code; there's a sample on the home page. Unfortunately it requires the use of ClearScript-specific "host variable" objects.

It might be possible to work around both issues with a translation layer. For example, if a script function takes a script array, call it through a wrapper that knows how to convert host arrays. If you must provide a host API that supports VBScript's ByRef semantics, create a VBScript pass-through that knows how to invoke the appropriate method using host variables.

Would something like that be feasible?

Cheers!
Sep 8, 2014 at 2:35 PM
Thanks for the quick reply!

A global option for array marshaling would be perfect, if it'd be possible to add it at some point. And thanks for the suggestion of a translation layer - I'm not sure why I didn't think of that before. That may well solve most of the problems we've currently got.

Cheers,

Owen