我将面临以下问题将近一周:我有一个c#结构数组,需要将其发送到COM应用程序。但是当我调用COM方法时,我得到以下内容
错误:System.Runtime.InteropServices.MarshalDirectiveException' 发生
附加信息:无法编组'参数#5':无效 托管/非托管类型组合(Int / UInt必须与 SysInt或SysUInt)。
使用C#接口扩展/派生IDL文件。
以下是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[]
);
c#界面:
[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的定义是:
[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
}
调用COM方法的代码片段:
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]);
}
// Notify COM component
//here i get the error
myComObject.MyRequestFinished(callId,
((uint)lengthElemArray1),
pMyElemArray1,
((uint)lengthElemArray2),
pMyElemArray2);
//....
}
答案 0 :(得分:0)
LPArray
不适用于IntPtr
类型的参数。尝试将参数类型更改为数组或删除MarshalAs
属性。
void MyRequestFinished(
[In]
long callId,
[In]
uint nrElemArray1,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
MyStruct[] ElemArray1,
[In]
uint nrElemArray2,
[In]
IntPtr ElemArray2);
}
就个人而言,我更喜欢传入一个数组而不是一个IntPtr,因为它会在调用站点产生更简单的逻辑。