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

时间:2009-03-19 03:59:32

标签: c# .net pinvoke

这就是我所拥有的:

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

  • 我想从中调用DLL的C#项目。

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

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

2 个答案:

答案 0 :(得分:4)

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

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

您需要在桌面DC上调用CreateCompatibleDC(),这是从GetDC(NULL)获得的,然后是刚刚创建的DC上的CreateCompatibleBitmap()。然后调用GetDIBits()。

答案 1 :(得分:1)

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

我想这需要分解为步骤......

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

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

您可以使用

分配非托管缓冲区
IntPtr pnt = Marshal.AllocHGlobal(size);

您可以使用

复制字节数组
Marshal.Copy(theByteArray, 0, pnt, theByteArray.Length);

注意,因为它的非托管数据,您将负责在完成后释放它。

Marshal.FreeHGlobal(ptr)

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