[英]Passing an array of Structures from C++(COM) to C#
我正在尝试将结构数组从C ++(COM)传递给C#
//C++ definition
//MyStruct being a COM Visible Structure
HRESULT GetArrofStruct([in,out] LONG* count, [out,size_is(,*pnCnt)] MyStruct** ppArr);
//C# definition
void GetArrofStruct(ref int Count,out IntPtr outPtr);
//I use the Function Something like this in C#
IntPtr buffer = IntPtr.Zero;
int Count;
GetArrofStruct(ref Count,out buffer);
MyStruct[] arrayManaged = new MyStruct[Count];
for (int i = 0, nElemOffs = (int)buffer; i < Count; i++)
{
ru[i] = (MyStruct)Marshal.PtrToStructure((IntPtr)nElemOffs, typeof(MyStruct));
nElemOffs += Marshal.SizeOf(typeof(MyStruct));
}
在for循环中,第一个元素被正确编组,第二个元素开始,我得到一个AccessViolation。
在C ++方面,数组似乎已正确填充。(已通过调试验证)。
您使用的是指针指针,因此只需要按指针的大小而不是struct的大小来增加偏移量(nElemOffs)并取消引用它即可。
您正在C ++端使用MyStruct**
而不是MyStruct*
,这意味着您需要先取消引用它,然后再将指针值转换为结构。
样例代码:
int Count;
IntPtr pBuffer;
GetArrofStruct(ref Count,out pBuffer);
MyStruct[] arrayManaged = new MyStruct[Count];
unsafe
{
Int32 buffer = (int)pBuffer;
for (int i = 0; i < Count; i++)
{
// Read the memory position of the structure
Int32 p = *((Int32*)buffer);
arrayManaged[i] = (MyStruct)Marshal.PtrToStructure((IntPtr)p, typeof(MyStruct));
buffer += 4; // increase by pointer size
}
}
确保您的结构MyStruct
在C#和C ++端具有相同的大小, [StructLayout(..)]
在这里可能会有所帮助。
好吧,您的问题出在(int)缓冲区强制转换中。 运算符+在int和IntPtr上不同。 请看以下内容:
for (int i = 0; i < Count; i++)
{
IntPtr newPtr = buffer + i * sizeof(typeof(MyStruct));
ru[i] = (MyStruct)Marshal.PtrToStructure(newPtr, typeof(MyStruct));
}
我尚未对此进行测试,也不知道IntPtr的内容是否正确且分配正确,但这是您应如何遍历结构数组的方式。
至于封送问题,封送由IDL定义,因此请检查您的数组定义。 我不确定([out]数组总是让我感到困惑),但是在我看来,您的一维数太多了。 请尝试以下操作(如果正确,请告诉我):
[out,size_is(pnCnt)] MyStruct** ppArr
[out,size_is(*pnCnt)] MyStruct* ppArr
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.