2010-10-31 540 views

回答

3

您需要知道返回的字節的確切數量以及位圖尺寸(高度,寬度和編碼)。

[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實例。

+0

誰將處置'GetCurrentImage()'分配的內存? – Timwi 2010-10-31 17:24:26

+0

@Timwi當然取決於在外部DLL中定義的契約。也許有一個功能可以做到,或者可能需要添加。但是,當然,OP將需要考慮到這一點。如果內存是在非託管代碼中使用LocalAlloc分配的,則可以在託管代碼中使用Marshal.FreeHGlobal將其釋放。 – driis 2010-10-31 17:55:09

+0

明白了......唯一不合情理的是,圖片格式24bppRGB是BGR,而不是RGB – Thomas 2010-11-01 12:44:27

0

像這樣的事情的常見策略是傳入緩衝區並使函數填充緩衝區。否則,在處理分配的內存時會遇到麻煩;換句話說,你將會有內存泄漏。

所以,你應該有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 
0

如果你想保持在工作不安全的情況下,即使在C#中,您還可以通過繞過元帥和IntPtrs簡化一切如下:

[DllImport("Library.dll")] 
internal static unsafe extern Byte* GetCurrentImage(); 

請記住,將所有導入插入名爲NativeMethods的靜態類並將其聲明爲內部程序總是一個好習慣。