我如何确保在调用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