简体   繁体   中英

How do I pass an array of integers from classic asp to a c# COM object?

I'm trying to pass an array of integers from Classic ASP to a DLL created in C#.

I have the following C# method:

public int passIntArray(object arr)
{
    int[] ia = (int[])arr;
    int sum = 0;
    for (int i = 0; i < ia.Length; i++)
        sum += ia[i];

    return sum;
}

I've tried a number of ways to convert arr to an int[], but not having any success. My asp code is:

var arr = [1,2,3,4,5,6];
var x = Server.CreateObject("dllTest.test");
Response.Write(x.passIntArray(arr));

I am currently getting the following error:

Unable to cast COM object of type 'System.__ComObject' to class type 'System.Int32[]'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.

Can anyone tell me how to do it or tell me it can't be done?

Using the code on this very useful page http://www.add-in-express.com/creating-addins-blog/2011/12/20/type-name-system-comobject/ I have managed to find out that the type of the passed parameter is "JScriptTypeInfo" if that's of any use.

If I add:

foreach (object m in arr.GetType().GetMembers())
    // output m

I get the following output:

System.Object GetLifetimeService()
System.Object InitializeLifetimeService()
System.Runtime.Remoting.ObjRef CreateObjRef(System.Type)
System.String ToString()
Boolean Equals(System.Object)
Int32 GetHashCode()
System.Type GetType()

As explained in the SO item I suggested was a duplicate , you would change your ASP code thus:

function getSafeArray(jsArr) 
{
  var dict = new ActiveXObject("Scripting.Dictionary");     
  for (var i = 0; i < jsArr.length; i++)     
    dict.add(i, jsArr[i]);     
  return dict.Items(); 
} 
var arr = [1,2,3,4,5,6]; 
var x = Server.CreateObject("dllTest.test"); 
Response.Write(x.passIntArray(getSafeArray(arr))); 

You should also change your C# method signature to:

public int passIntArray(object[] arr) // EDITED: 17-Sept

or

public int passIntArray([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_I4)]  int[] arr)

The point is that you are not really trying to go from JavaScript to C#, you are going from JavaScript to COM: you can only interface the C# DLL at all because it is ComVisible and is registered in the COM registry with a ProgID which Server.CreateObject can look up. With the signature change, your DLL's COM-exposed interface will expect to receive an unmanaged SAFEARRAY and the script code above is a way to get JavaScript to provide one, using the COM Scripting.Dictionary as a sort of custom marshaler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM