【问题标题】:How can I pass a .NET Bitmap to a native DLL?如何将 .NET 位图传递给本机 DLL?
【发布时间】:2009-03-19 12:42:10
【问题描述】:

这是我所拥有的:

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

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

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

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

【问题讨论】:

    标签: c# .net pinvoke


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

      我想这需要分解成几个步骤......

      [未经测试,但我认为总体思路是合理的]

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

      您可以使用

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

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

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

      请注意,由于它的数据不受管理,您将负责在完成后释放它。

      Marshal.FreeHGlobal(ptr)
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多