我導出了以下C函數以在DLL文件中調用。將C uint8_t指針轉換爲C#字節數組
uint8_t* _stdcall GetCurrentImage();
現在我想在C#中調用這個函數來獲取位圖圖像。 我該怎麼做?
在此先感謝!
我導出了以下C函數以在DLL文件中調用。將C uint8_t指針轉換爲C#字節數組
uint8_t* _stdcall GetCurrentImage();
現在我想在C#中調用這個函數來獲取位圖圖像。 我該怎麼做?
在此先感謝!
您需要知道返回的字節的確切數量以及位圖尺寸(高度,寬度和編碼)。
[DllImport("yourlib.dll")]
private static extern IntPtr GetCurrentImage();
的IntPtr的你從任何可以使用Marshal.Copy
使用,以獲得原始字節:然後你就可以在C#聲明它
byte[] buffer = new byte[length];
IntPtr beginPtr = GetCurrentImage();
Marshal.Copy(beginPtr, buffer,0,length);
最後,聲明與尺寸的Bitmap你的圖片和PixelFormat使用(如果它是一個非標準的像素格式,你可能必須自己做一些轉換)。然後,您可以將數據複製到原始位圖字節中,方法是使用LockBits獲取指向原始位圖數據的BitmapData實例。
像這樣的事情的常見策略是傳入緩衝區並使函數填充緩衝區。否則,在處理分配的內存時會遇到麻煩;換句話說,你將會有內存泄漏。
所以,你應該有C函數像這樣...
uint32_t _stdcall GetCurrentImageSize();
void _stdcall GetCurrentImage(uint8_t* buffer, int offset, int bufferSize);
然後在C#中,你會做這樣的事情......
var buffer = new byte [ GetCurrentImageSize() ];
fixed (byte* b = &buffer[0])
GetCurrentImage(b, 0, buffer.Length);
// 'buffer' now contains the image
如果你想保持在工作不安全的情況下,即使在C#中,您還可以通過繞過元帥和IntPtrs簡化一切如下:
[DllImport("Library.dll")]
internal static unsafe extern Byte* GetCurrentImage();
請記住,將所有導入插入名爲NativeMethods的靜態類並將其聲明爲內部程序總是一個好習慣。
誰將處置'GetCurrentImage()'分配的內存? – Timwi 2010-10-31 17:24:26
@Timwi當然取決於在外部DLL中定義的契約。也許有一個功能可以做到,或者可能需要添加。但是,當然,OP將需要考慮到這一點。如果內存是在非託管代碼中使用LocalAlloc分配的,則可以在託管代碼中使用Marshal.FreeHGlobal將其釋放。 – driis 2010-10-31 17:55:09
明白了......唯一不合情理的是,圖片格式24bppRGB是BGR,而不是RGB – Thomas 2010-11-01 12:44:27