2013-07-18 23 views
3

我有一個IntPtr指向另一個IntPtr指向一個非託管數組。我想知道如何將這個非託管陣列複製到託管陣列?我知道我將不得不使用Marshal.Copy,但當我有一個指針指針時,我不確定如何使用它。如何從這個數組中檢索信息?

這裏是我的示例代碼

非託管C++:

void foo(Unsigned_16_Type** Buffer_Pointer); 

託管C#:

[DllImport("example.dll")] 
     public static extern void foo(IntPtr Buffer_Pointer); 
//... 
//... 

int[] bufferArray = new int[32]; 


IntPtr p_Buffer = (IntPtr)Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)) * bufferArray.Length); 
Marshal.Copy(bufferArray, 0, p_Buffer, bufferArray.Length); 

GCHandle handle = GCHandle.Alloc(p_Buffer, GCHandleType.Pinned); 
IntPtr ppUnmanagedBuffer = (IntPtr)handle.AddrOfPinnedObject(); 

//Call to foo 
foo(ppUnmanagedBuffer); 

所以現在在這一點上我有一個的IntPtr到一個IntPtr裏面ppUnmanagedBuffer數組但我不確定如何使用Marshal將該陣列複製到新的受管理的陣列。複製

我想是這樣

int[] arrayRes = new int[word_count]; 
Marshal.Copy(ppUnmanagedBuffer, arrayRes, 0, word_count); 

但是,這並不工作

回答

0

剩下的唯一的事情就是「撤銷」下面的調用來獲得ppUnmanagedBuffer指向數據你期望的類型:

GCHandle handle = GCHandle.Alloc(p_Buffer, GCHandleType.Pinned);

IntPtr ppUnmanagedBuffer = (IntPtr)handle.AddrOfPinnedObject();

如果C#已經設法連鎖行業Ë您的int**通過這種機制,相當於,那麼你需要取消對它的引用,一旦獲得等同於int[],像這樣:

Marshal.Copy((IntPtr)(GCHandle.FromIntPtr(ppUnmanagedBuffer).target), arrayRes, 0, word_count);

(語法可能會關閉了一點,但這是一般的想法...)

+0

第三個參數是起始索引 Marshal.Copy(IntPtr source,int [] destination,int startIndex,int length); 我將如何應用derefence? – user2134127

+0

我的第一個副本是將一個int數組複製到一個IntPtr中,第二個副本是將一個IntPtr複製到一個int數組中。這就是爲什麼論點不同。此外,我不能在C#中使用指針和引用,是否有我可以使用的等價物? – user2134127

+0

我相信我現在的答案現在是正確的。我很抱歉發佈,但沒有花時間充分理解。 – abiessu