2012-01-16 53 views
2

我有一個C DLL,它對圖像執行一些處理並返回結果。所以我想從.NET端傳遞一張圖片,但是現在我被卡住了,我不確定這是關於類型,編組的錯綜複雜還是語法。由於我是一個noob它可能是所有三個。如何使用PInvoke傳遞圖像

我可以在有問題的DLL中調用其他函數,所以至少有一些基礎已經到位。例如,當我打電話時:

IntPtr versionIntPtr = GetDLLVersionNumber(); 
string version = Marshal.PtrToStringAnsi(versionIntPtr); 
Console.WriteLine("DLL version number reported as: " + version); 

並且這個工作非常好,將當前版本的DLL打印到控制檯。

當我看它使用相同的函數C代碼示例中,它出現使用的功能如下:

unsigned char* ExtractImageInfo(const char* pixels, size_t width, size_t height) 

(I也有其中相同的功能被提到的標頭文件,如下所示:

... ExtractImageInformation(struct ImageData image, void* imageInformation); 

,但我真的不知道這是什麼意思)

所以我嘗試使用此功能去如下:

首先我指定的接口的DLL:

[DllImport("C:\\MyDLL", EntryPoint = "ExtractImageInfo", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 
public static extern IntPtr ExtractImageInfo(IntPtr image, UInt32 imageWidth, UInt32 imageHeight); 

然後,我得到正確類型的圖像,並且獲得其尺寸:

Bitmap bitmap1 = (Bitmap)Image.FromFile("C:\\Images\\myImage.bmp"); 
UInt32 _imageWidth = Convert.ToUInt32(bitmap1.Width); 
UInt32 _imageHeight = Convert.ToUInt32(bitmap1.Height); 

然後我得到的指針圖像(因爲我認爲這就是我需要傳遞):

IntPtr bitmap1Ptr = bitmap1.GetHbitmap(); 

然後我調用函數...

IntPtr myProcessedImage; 
myProcessedImage = ExtractImageInfo(bitmap1Ptr, _imageWidth, _imageHeight); 

但它不起作用 - 我不回到我處理的數據的指針。我在這裏想知道的很大一部分是我是否以正確的方式傳遞圖像,以及我的本地函數接口的語法是否正確。我想這兩個答案可能都不是!

我只有閱讀和使用的PInvoke試驗了幾天,所以如果有人能指出我的我的方式錯誤我會:-)

+0

從它的外觀來看,您的本機DLL會暴露許多內存泄漏... – leppie 2012-01-16 11:11:17

回答

3
unsigned char* ExtractImageInfo(const char* pixels, size_t width, size_t height) 

的名字永遠感激該參數強烈建議它需要一個指向原始像素數據的指針。您可以從Bitmap.LockBits(),BitmapData.Scan0屬性中獲取一個。不要調用UnlockBits()直到函數返回。

函數的返回類型是一個重要的內存管理問題。無論返回什麼緩衝區指針都幾乎肯定會被釋放。您無法從託管代碼中執行此操作,您無權訪問此C代碼使用的分配器來調用正確版本的free()。調用這個函數一百萬次,並仔細檢查你是否沒有失控內存泄漏。如果你這樣做,那麼你不能捏住它,一個C++/CLI包裝是必需的,儘管它正常工作的機率也相當渺茫。這是一個設計不好的功能,很難從任何代碼使用,包括C.