1

I have looked at tutorials on jscript arrays, but not seeing it yet. I saw something similar asked but involving Win32 code not .NET.

Wondering, how do I pass arrays back and forth between JScript and a C# COM component?

For example, I have two properties defined in my C# COM that returns string and integer arrays as:

string[] HeaderLines { get; set; }
int[] ImagePixels { get; set; }

In my test.js file:

...

var T = new ActiveXObject("Imager.Reader"); 
...    
var headerLines = T.HeaderLines;
WScript.StdOut.WriteLine("First HeaderLine:" + headerLines[0]);
var pixels = T.ImagePixels;
WScript.StdOut.WriteLine("First Pixel: " + pixels[0]);

The error is where headerLines[0] is written out: C:\temp\test.js(12, 1) Microsoft JScript runtime error: 'headerLines.0' is null or not an object

If I remove the headerLines in test.js, then I get this error (essentially the same but for the integer array): C:\temp\test.js(12, 1) Microsoft JScript runtime error: 'pixels.0' is null or not an object

I can get results from non-array properties just fine as well as passing values to other methods, but not with arrays. I also need to pass in string and integer arrays into a method defined in my C# COM component as:

bool Write(string filename, string[] headerLines, int[] pix, int width, int height);

I am using Visual Studio Express 2012 for Desktop for creating the COM piece in C#. If any other information is needed, just let me know.

2
  • have you tried calling length to see if it is an array? Commented Jan 6, 2014 at 3:03
  • thanks. I get the error: "C:\temp\test.js(12, 1) Microsoft JScript runtime error: 'headerLines.length' is null or not an object". To test.js I added the following to get this error:var headerLines = T.HeaderLines; var headerLinesLength = headerLines.length; WScript.StdOut.WriteLine("HeaderLine Length:" + headerLinesLength); Commented Jan 6, 2014 at 3:46

1 Answer 1

1

Microsoft JScript engine implements JavaScript arrays as IDispatchEx objects. From C#, they can be manipulated via reflection or as dynamic objects (with dynamic, it's only possible to access properties and methods like length, push() etc., but not reference actual elements by their indices). Example:

JavaScript:

var T = new ActiveXObject("MySimulator.World"); 

var ar = ["a", "b", "c"];

T.MyFunction(ar);

C#:

public void MyFunction(object array)
{
    dynamic dynArray = array;
    int length = dynArray.length;
    dynArray.push("d");

    SetAt(array, 1, "bb"); 

    Console.WriteLine("MyFunction called, array.length: " + length);
    Console.WriteLine("array[0]: " + GetAt(array, 0));
    Console.WriteLine("array[1]: " + GetAt(array, 1));
    Console.WriteLine("array[3]: " + GetAt(array, 3));
}

static object GetAt(object array, int index)
{
    return array.GetType().InvokeMember(index.ToString(),
        System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.GetProperty,
        null, array, new object[] { });
}

static object SetAt(object array, int index, object value)
{
    return array.GetType().InvokeMember(index.ToString(),
        System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.SetProperty,
        null, array, new object[] { value });
}

Output:

MyFunction called, array.length: 3
array[0]: a
array[1]: bb
array[3]: d
Sign up to request clarification or add additional context in comments.

4 Comments

Noseratio - thanks for all of the very good answers you have been providing! Does this answer mean I cannot use the arrays directly in jscript? I was hoping I could get back the string and integer arrays (i.e. HeaderLines and ImagePixels) mentioned at top and print them out directly (or portions of them). It sounds like I cannot? What is strange though is that when I query the length in jscript of my returned string and integer arrays I get an error (see my previous comment on this original post). Any ideas why this is happening? Thanks again for all of your help.
@Buck, no you cannot use JavaScript arrays directly or substitute them with C# arrays. They're not actual arrays in common sense, rather, they're objects. Deal with them as with objects, it should not be a big obstacle. If you need to pass a C# array to JavaScript, wrap it as an object (with Length, GetAt, SetAt methods) and pass the object to JavaScript.
@Buck, on a side note, if you just need a scripting glue for you .NET object, consider using PowerShell. It will give you much more than Windows Scripting Host does, and you could leave the COM/interop stuff behind.
Great to hear about PowerShell - thanks! Also, your other answers were the core of my understanding how jscript worked so I could implement a final solution. Based on that, it is rock solid. Best,

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.