I ran into the following problem for almost a week: I have an array of C # structure that needs to be sent to a COM application. But when I call the COM method, I get the following
error: System.Runtime.InteropServices.MarshalDirectiveException 'occurred
Additional Information: Cannot marshal parameter # 5: Invalid managed / unmanaged type combination (Int / UInt must be mated to SysInt or SysUInt).
The IDL file is expanded / displayed using the C # interface.
Here is the method defined as in the IDL:
[helpstring("Method MyCallbackMehtod")]
HRESULT MyRequestFinished(
[in] long callId,
[in] unsigned int nrElemArray1,
[in, size_is(nrElemArray1)] MyStruct ElemArray1[],
[in] unsigned int nrElemArray2,
[in, size_is(nrElemArray2)] MyStruct ElemArray2[]
);
Interface with#:
[ComImport, Guid("xxxxxxxx-xxxx-xxxx-xxx-xxxxxxxxxx")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IMyInterface
{
void MyRequestFinished(
[In]
long callId,
[In]
uint nrElemArray1,
[In,MarshalAs(UnmanagedType.LPArray,SizeParamIndex=1)]
IntPtr ElemArray1,
[In]
uint nrElemArray2,
[In, MarshalAs(UnmanagedType.LPArray,SizeParamIndex = 3)]
IntPtr ElemArray2);
}
MyStruct definition:
[StructLayout(LayoutKind.Sequential,Pack=1)]
public struct MyStruct
{
public double setValue;
public double actualValue;
[MarshalAs(UnmanagedType.I4)]
public MyEnum myResult;
}
[ComVisible(true)]
public enum MyEnum
{
Val1,
Val2,
Val3
}
A snippet of code that calls the COM method call:
IntPtr pMyElemArray1 = IntPtr.Zero;
IntPtr pMyElemArray2 = IntPtr.Zero;
MyStruct[] MyElemArray1= GetArray1();
MyStruct[] MyElemArray2= GetArray2();
int lengthElemArray1= MyElemArray1.Length;
int lengthElemArray2= MyElemArray2.Length;
pMyElemArray1 = Marshal.AllocCoTaskMem(Marshal.SizeOf(MyElemArray1[0]) * lengthElemArray1);
pMyElem2 = Marshal.AllocCoTaskMem(Marshal.SizeOf(MyElemArray2[0]) * lengthElemArray2);
int rundef = (int)pMyElemArray1 ;
for (int i = 0; i < lengthElemArray1; i++)
{
Marshal.StructureToPtr(MyElemArray1 [i], (IntPtr)rundef, false);
rundef += Marshal.SizeOf(MyElemArray1[i]);
}
rundef = (int)pMyElemArray2;
for (int i = 0; i < lengthElemArray2; i++)
{
Marshal.StructureToPtr(MyElemArray2[i], (IntPtr)rundef, false);
rundef += Marshal.SizeOf(MyElemArray2[i]);
}
myComObject.MyRequestFinished(callId,
((uint)lengthElemArray1),
pMyElemArray1,
((uint)lengthElemArray2),
pMyElemArray2);
}