加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 如何在调用FreeLibrary之前确保释放接口实例

发布时间:2020-12-15 09:30:14 所属栏目:大数据 来源:网络整理
导读:我有一个dll导出一个返回接口的函数. 我为LoadLibrary,GetProcAddress和FreeLibrary函数创建了一个包装器,用于调用导出的函数. TInterfaceGetter = classprivate...public constructor Create; destructor Destroy; override; function GetInterface: IMyInt
我有一个dll导出一个返回接口的函数.

我为LoadLibrary,GetProcAddress和FreeLibrary函数创建了一个包装器,用于调用导出的函数.

TInterfaceGetter = class
private
...
public
  constructor Create;
  destructor Destroy; override;
  function GetInterface: IMyInterface;
end;

当第一次调用GetInterface时,这个包装器延迟加载dll并缓存模块句柄和导出函数的proc地址.对FreeLibrary的调用发生在包装器的析构函数中.

除非客户端代码在释放包装器后挂起到接口引用上,否则一切都会很好地工作.当接口引用最终超出作用域时,对_IntfClear的结果调用会引发访问冲突,因为dll以及它正在使用的任何内存已经从客户端的内存空间中卸载.

我怎样才能优雅地处理这件事?完整的COM实现如何处理这种情况?

解决方法

COM通过将责任转移到DLL来处理此问题. DLL需要实现并导出名为DllCanUnloadNow的函数. COM偶尔会调用它,如果它返回true,则可以卸载DLL.

那么这个功能怎么知道呢? DLL通过调用DllGetClassObject来跟踪它给出的对象数量,并且它知道有多少对象仍处于活动状态.在Delphi的默认COM DLL实现中,它维护一个全局对象计数,就像每个对象维护自己的引用计数一样.例如,请参阅ComServ.pas中的实现.

您可以使用相同的技术.跟踪GetInterface函数给出的内容以及已发布的内容.导出另一个函数,以便主程序可以询问卸载库是否安全.

另一种方法是将您的DLL更改为真正的COM DLL

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读