Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing array from JScript to COM object: Error converting argument 1 to type class StringArray #631

Open
FrankLeinbach opened this issue Jan 24, 2025 · 4 comments
Assignees
Labels

Comments

@FrankLeinbach
Copy link

Discussed in #630

Originally posted by FrankLeinbach January 24, 2025
I have run into a breaking issue in moving from an implementation I made of IActiveScript to ClearScript.

I have JScript that creates a COM object like this:

var thirdPartyObj = new ActiveXObject("ThirdPartyObj.API");

within the script, I also create an array of strings to pass to a method on this object:

var stringData = [];
stringData.push("String1");
stringData.push("String2");
stringData.push("String3");

In the previous iteration, I had a problem directly calling the third party object's method with this array, like this:

thirdPartyObj.ProcessStrings(stringData)

This gave me an error. To circumvent this, I created a global host object function that simply took the JavaScript array and returned an array of String (string[]).

thirdPartyObj.ProcessStrings(JSArrayToStringArray(stringData));

This worked in the original IActiveScript implementation.

Now, with ClearScript, every time I pass this to the ProcessStrings function, regardless of passing it directly or wrapping the array in the function, I get the error "Error converting argument 1 to type class StringArray".

I have tried a number of engine properties, but none have worked:

AllowReflection
DisableListIndexTypeRestriction
DisableTypeRestriction
EnableAutoHostVariables
EnforceAnonymousTypeAccess
UseReflectionBindFallback

Any insight would be appreciated.

@ClearScriptLib
Copy link
Collaborator

ClearScriptLib commented Jan 24, 2025

Hi @FrankLeinbach,

First, a general comment: Because ClearScript's primary goal is to provide full access to .NET from script code, its default behavior is to marshal most .NET objects, including arrays, by proxy. So, instead of an array type that's native to the script language, script code gets a special object – a proxy – that acts as a reference to the managed array and provides full access to it. The script engine has no way of determining that the proxy refers to an array and no way of converting it to another array type.

Now, with ClearScript, every time I pass this to the ProcessStrings function, regardless of passing it directly or wrapping the array in the function, I get the error "Error converting argument 1 to type class StringArray".

It's difficult to answer without knowing what ProcessStrings expects for an argument – that is, what exactly the definition of StringArray is. However, if we assume that, in your original, working scenario, you passed a managed string array (the return value from JSArrayToStringArray) directly to JScript via COM Interop, then ClearScript's MarshalArraysByValue feature might help. Could you give it a try?

Thanks!

@FrankLeinbach
Copy link
Author

Thank you for the quick response. I will try this on Monday when I'm back at my computer and post whether or not it worked.

@FrankLeinbach
Copy link
Author

This appears to work. Thank you for the help.

Are there any issues that are brought up by MarshalArraysByValue?

@ClearScriptLib
Copy link
Collaborator

ClearScriptLib commented Jan 27, 2025

Hi @FrankLeinbach,

This appears to work. Thank you for the help.

That's great to hear. Thank you!

Are there any issues that are brought up by MarshalArraysByValue?

Yes, there are caveats:

  1. The flag affects all managed arrays that the host passes or returns to the script engine. The feature cannot be used selectively.
  2. A managed array can reference itself – either directly or indirectly. COM Interop cannot marshal such an array correctly, so ClearScript leaves array elements that would create circular references unassigned – i.e., null.
  3. The conversion of a managed array to a script array is lossy. The script array should contain all the data in the correct order (except as noted above), but .NET-specific array functionality will not be accessible – e.g., methods such as Clear and Reverse, interfaces such as ICloneable and IEnumerable, etc.

Good luck!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants