思路:C++ DLL中結構體的指針成員返回給C#時,其實返回的是一個地址。在C#中使用這個地址來定位在C++ DLL中分配的非托管的內存塊,並把其復制到C#中托管的內存中,然后進行需要的操作。
下面以例子來說明:
我的需求是:用C++ DLL中的函數對壓縮圖片進行解碼,並把解出的圖片數據返回給C#。
在C++ DLL中定義的存儲圖片文件的結構是:
1 typedef struct _OGLTexHeader 2 { 3 int target; 4 int width; 5 int height; 6 int depth;
7 int imageSize; 8 unsigned byte *data; 9 } OGLTEXHEADER
在C#中使用四字節的int來接收這個地址(我用的是32位的OS),其代碼是:
1 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 2 public struct OGLTEXHEADER 3 { 4 public int target; 5 public int width; 6 public int height; 7 public int depth; 8 public int imageSize; 9 public int data; 10 }
執行完C++ DLL后,結構體中的data成員指向了一個內存塊,在返回給C#時,返回其地址。C#中接收data指向的內存塊的代碼是:
1 IntPtr texInfo = //從C++ DLL中返回的結構體的指針 2 OGLTEXHEADER header = (OGLTEXHEADER)Marshal.PtrToStructure(texInfo, typeof(OGLTEXHEADER)); 3 int width = header.width; 4 int height = heaer.height; 5 6 IntPtr dataAddress = (IntPtr)header.data; //獲取地址 7 byte[] data = new byte[width * height * 4]; 8 //使用地址dataAddress來獲取需要的內存塊中的數據 9 Marshal.Copy(dataAddress, data, 0, width * height * 4);
這樣就把指針指向的非托管的內存塊中的數據拷貝到了托管的內存中。
