我有一个应用程序,它加载了一个使用Delphi GDI + Library的DLL .该应用程序在卸载DLL(Calling FreeLibrary)时挂起.
我将问题跟踪到GdiPlus.pas单元终结部分,该部分调用GdiPlusShutdown,它永远不会返回.
如何避免这种僵局?
GdiPlusShutdown(和 GdiPlusStartup 顺便说一句)不能从 DllMain 调用,但当调用 FreeLibrary 时,DllMain 由 Windows 和 Delphi 运行时调用:Delphi 调用 DLL 使用的所有单元的终结部分,并且 GdiPlus 终结部分调用 GdiPlusShutdown (这在使用时完全可以)来自可执行文件)。与初始化部分类似的行为。
我通过在初始化和终结部分添加 IsLibrary 测试来解决此问题,以避免调用有问题的函数,还添加了两个公共过程 InitializeForDll 和 FinalizeForDll。通过这些微小的更改,DLL 能够导出调用 InitializeForDll 和 FinalizeForDll 的函数。这些导出的函数必须在加载 DLL 之后和卸载 DLL 之前由托管应用程序调用。
以下是我对 GdiPlus.pas 所做的更改:
在界面部分:
var
procedure InitializeForDll;
procedure FinalizeForDll;
Run Code Online (Sandbox Code Playgroud)
在实施部分:
procedure InitializeForDll;
begin
Initialize;
end;
procedure FinalizeForDll;
begin
Finalize;
end;
Run Code Online (Sandbox Code Playgroud)
还更新了初始化和终结部分,如下所示:
Initialization
if not IsLibrary then
Initialize;
Finalization
if not IsLibrary then
Finalize;
Run Code Online (Sandbox Code Playgroud)
在 DLL 中,我导出了这些函数:
procedure Initialize; stdcall;
begin
GdiPlus.InitializeForDll;
end;
procedure Finalize; stdcall;
begin
GdiPlus.FinalizeForDll;
end;
Run Code Online (Sandbox Code Playgroud)
Initialize 和 Finalize 由托管应用程序在调用 LoadLibrary 之后和调用 FreeLibrary (或任何将加载/卸载 DLL 的内容)之前调用。
我希望这会帮助其他人。顺便说一句:感谢Eric Bilsen提供Delphi GdiPlus 库
| 归档时间: |
|
| 查看次数: |
1234 次 |
| 最近记录: |