【问题标题】:Prevent GDI leaks in dll防止 dll 中的 GDI 泄漏
【发布时间】:2015-08-03 14:26:05
【问题描述】:

有一个在 dll 中使用的图形库,加载到进程中。似乎库泄漏(在加载/卸载期间,进程资源管理器属性对话框中的 GDI 句柄计数在整个进程中不断增长)。

有没有办法将 dll 创建的所有 GDI 句柄存储在一个进程中,以便在 dll 卸载后将它们全部删除?说,挂钩 CreateBitmap() 等等?但是如何判断资源是不是我们的dll创建的,而不是进程本身呢?

问候,

【问题讨论】:

  • 我确信 DLL 公开了必须调用才能初始化和取消初始化库的函数。你叫那些?除此之外,您必须修复库。请参阅Debugging a GDI Resource Leak 以获得有用的建议。
  • @IInspectable 是的,他们被调用了。谢谢你的链接。

标签: c++ winapi dll gdi resource-leak


【解决方案1】:

有没有办法将 dll 创建的所有 GDI 句柄存储在一个进程中,以便在 dll 卸载后将它们全部删除?说,挂钩 CreateBitmap() 等等?但是如何判断资源是不是我们的dll创建的,而不是进程本身呢?

没有。您将需要从源头上解决此问题。如果 DLL 确实在泄漏句柄,则必须修复 DLL。

【讨论】:

    【解决方案2】:

    关闭由 DLL 打开的所有句柄并释放所有资源的方法是使用一个单独的进程,该进程加载 DLL 并在 DLL 卸载后终止。因此,您可以评估哪个工作量更大:修复 DLL,找到另一个 DLL(不会泄漏并且可能没有很多其他陷阱),或者实现进程间通信以释放句柄并仍然使用动态链接库。如果选择后一种方式,则可以使用共享内存块在进程之间传输绘制的位图,使用命名事件进行同步等。

    【讨论】:

      【解决方案3】:

      要确定调用者必须获取每个调用的堆栈跟踪,请查看RtlCaptureStackBackTrace

      我会尝试做的另一种方法是修改此 DLL(我假设您只有一个 DLL 二进制文件,而不是源代码:否则您可以修复泄漏)以使其使用 GDI33.DLL 而不是 GDI32.dll .然后您创建 GDI33.DLL 导出该 dll 使用的那些函数。 GDI33.DLL 将调用转发到 GDI32.dll 并收集 GDI 对象句柄。

      【讨论】:

        猜你喜欢
        • 2020-02-25
        • 2014-02-10
        • 2013-06-10
        • 2010-10-03
        • 1970-01-01
        • 2016-07-10
        • 2011-12-05
        相关资源
        最近更新 更多