如何将.NET位图传递给本机DLL?

这是我有的:

  • 一个外部DLL,我用C编写。这个DLL链接到opencv。 我不想直接从C#调用OpenCV – 已经有大量的C代码访问OpenCV,它将在DLL中使用。 有一个导出函数: passbitmap(void * mem,size_t s);

  • 我希望从中调用DLL的AC#项目。

  • 一个System.Drawing.Bitmap对象,我想以某种方式将像素/位图数据传递给我的DLL。

我猜它是某种P / Invoke,但我从来没有这样做过,在这种情况下我不知道如何正确地做到这一点。 我该怎么办?

您需要调用Bitmap.GetHbitmap()来获取位图的本机句柄。

然后你基本上想要做一些原生互操作并调用GetDIBits() 。 让你的目标dll实际调用GetDIBits()并传递win32句柄,而不是互操作可能会更好。

您需要在桌面DC上调用CreateCompatibleDC(),它来自GetDC(NULL),然后是您刚刚创建的DC上的CreateCompatibleBitmap()。 然后调用GetDIBits()。

C函数原型只需要一个指向缓冲区的指针和缓冲区的大小,它希望在缓冲区内看到的是$ 64K的问题。 我的假设/猜测是它是ByteArrayforms的Bitmap位。 所以…

我想这需要分解成几步……

[未经测试,但我认为一般的想法是合理的]

*从你的位图获取数据,可能是一个字节数组
*分配一个非托管缓冲区来存储数据
*将字节数组复制到缓冲区。
*将缓冲区指针传递给您的C dll
*完成后释放缓冲区

您可以使用分配非托管缓冲区

IntPtr pnt = Marshal.AllocHGlobal(size); 

你可以使用复制你的字节数组

 Marshal.Copy(theByteArray, 0, pnt, theByteArray.Length); 

请注意,因为它是非托管数据,所以当您完成后,您将负责释放它。

 Marshal.FreeHGlobal(ptr) 

请注意,正如@jeffamaphone所说,如果您可以访问c代码,那么简单地传递位图句柄会好得多。