2011-11-06 55 views
1

我試圖從C++(COM)通過結構的陣列,以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++端數組似乎被正確填充(通過調試驗證)。

+0

C++聲明非常荒謬,什麼是',* pnCnt'?無論如何,你無法直接使用它從C#中,無法釋放陣列的內存。 –

+0

對不起,在C++聲明中* pnCnt實際上是* count。然後我在C#代碼的for循環之後使用Marshal.FreeCoTaskMem(buffer)釋放數組的內存。 – Karthik

+0

有沒有任何答案可以解決您的問題? –

回答

0

您正在使用指針指針,因此您只需要按指針的大小增加偏移量(nElemOffs),而不是結構體的大小並對其進行解引用。

說明:

您在C++方面的,而不是使用MyStruct*MyStruct**,這意味着你的指針值轉換成一個struct之前必須取消對它的引用。

示例代碼:

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(..)]這可能有所幫助。

+0

嗨費利克斯,這似乎並沒有工作。 – Karthik

+0

嗨Karthik,我解釋了一點。 –

0

那麼,你的問題是在(int)緩衝區轉換。 Operator +在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,size_is(pnCnt)] MyStruct** ppArr 

[out,size_is(*pnCnt)] MyStruct* ppArr 
+0

我試過這樣做,這樣做不會引起訪問衝突異常。但只有數組ru [0]的第一個元素似乎正確編組,其餘的我得到垃圾/垃圾值。 – Karthik