如何獲取C#調用C++ DLL時返回的結構體中的指針成員所指向的內存塊


思路: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);

這樣就把指針指向的非托管的內存塊中的數據拷貝到了托管的內存中。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM