[英]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.