【问题标题】:Solution for unmanaged buffer assigned to a managed Image分配给托管图像的非托管缓冲区的解决方案
【发布时间】:2013-06-20 11:29:25
【问题描述】:

我有一个从本地 DLL 获取的位图图像的 char* 缓冲区。

我正在使用 C++/CLI 将本机 DLL 导出到 .Net

我想从缓冲区创建一个 Drawing.Bitmap 对象,而不需要额外的副本。
这可以通过其中一个构造函数来完成。

问题是内存管理问题,如何在 GC 收集到 Image 时删除缓冲区?

我想扩展 Bitmap,保留指向缓冲区的指针,并覆盖析构函数。

但是,如您所知,Bitmap 是密封的,而 Image 不能被继承....
有什么想法吗?

【问题讨论】:

  • 如果您的托管接口可以公开位图或图像以外的其他内容,那么您可以创建一个一次性包装器并将一些方法转发给位图,或者直接通过以下方式公开底层位图一个属性。
  • @Pragmateek 暴露底层位图的问题是它将持有不同的引用计数器,并且在包含类被销毁后仍可能使用。我想让包含类保持活动状态,直到没有人再使用位图了
  • 所以你必须完全封装位图。通过使用 IDisposable,调用者可以使用“使用”或直接调用 Dispose 来决定自己的位图范围。
  • 好吧,告诉过你。一个很好的理由来复制位图像素。
  • @Pragmateek 这行不通,因为用户仍然可以获得对位图的引用,并用它做一些事情(例如以表格形式显示)但是最初保存位图的类(和非托管数组)将被销毁

标签: c# c++ image bitmap c++-cli


【解决方案1】:

恭喜,您遇到了为什么强烈建议 DLL 填充调用方提供的缓冲区而不是返回指向在 DLL 中分配的内存的指针的主要示例。通过使用调用者提供的缓冲区,您允许调用者使用他喜欢的任何方法来管理其生命周期。 C++ 调用者可以使用智能指针。 .NET 调用者可以使用垃圾收集。与图像关联的缓冲区可以归位图实例所有。

在您的情况下,最好的解决方案是创建适当大小和像素格式的位图,调用 LockBits 以访问其内部缓冲区,并将指向该缓冲区的指针传递给 DLL,然后该 DLL 可以放置其直接输出到位图中。最后,拨打UnlockBits

【讨论】:

    猜你喜欢
    • 2016-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多