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.Copy 将该数组复制到一个新的托管数组

我尝试了类似的东西

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

但这不起作用

4

1 回答 1

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);

(语法可能有点偏离,但这是一般的想法......)

于 2013-07-18T17:22:16.107 回答