gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 15:11:19 27 4
gpt4 key购买 nike

我有一个 dll,它导出一个返回接口(interface)的函数。

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

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

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

一切都工作得很好,除非客户端代码在释放包装器后卡在接口(interface)引用上。当接口(interface)引用最终超出范围时,对 _IntfClear 的调用会引发访问冲突,因为 dll 及其使用的任何内存都已从客户端内存空间中卸载。

我该如何优雅地处理这个问题?完整的 COM 实现如何处理这种情况?

最佳答案

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

那么函数是如何知道的呢? DLL 通过调用 DllGetClassObject 来跟踪它发出的对象数量,并且它知道其中有多少对象仍然存在。在 Delphi 的默认 COM DLL 实现中,它维护全局对象计数,就像每个对象维护自己的引用计数一样。例如,请参阅 ComServ.pas 中的实现。

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

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

关于delphi - 如何确保在调用 FreeLibrary 之前释放 Interface 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18220136/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com