我如何确保在调用FreeLibrary之前释放Interface实例

我有一个DLL导出函数返回一个接口。

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

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

这个包装懒惰加载DLL并缓存模块句柄和proc地址的导出函数时首次调用GetInterface。 对FreeLibrary的调用发生在包装器的析构函数中。

除非客户端代码在释放封装之后挂在接口引用上,否则一切都可以很好地工作。 当接口引用最终超出范围时,对_IntfClear的调用将引发访问冲突,因为dll以及它使用的任何内存已经从客户端的内存空间中卸载。

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


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

那么该函数如何知道? 该DLL跟踪通过调用DllGetClassObject发出的对象数量,并知道这些对象中有多少仍处于活动状态。 在Delphi的默认COM DLL实现中,它维护着一个全局对象计数,就像每个对象维护自己的引用计数的方式一样。 例如,请参阅ComServ.pas中的实现。

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

另一种方法是将你的DLL改成一个真正的COM DLL

链接地址: http://www.djcxy.com/p/91029.html

上一篇: How do I ensure Interface instance is freed before FreeLibrary is called

下一篇: Memory leaks on DLL unload