delphi – 使用GdiPlus卸载DLL时程序挂起
我有一个应用程序加载使用
Delphi GDI+ Library的DLL.此应用程序在卸载DLL时挂起(Calling
FreeLibrary).
我将问题跟踪到GdiPlus.pas单元终结部分,该部分调用GdiPlusShutdown,它永远不会返回. 如何避免这种僵局? 解决方法GdiplusStartup 功能的文档说明了这一点:
通过将此Delphi GdiPlus库编译为DLL,您违反了GdiplusStartup和GdiplusShutdown的规则.这些函数分别在单元初始化和完成部分中调用.对于库项目,单元的初始化和完成部分中的代码从DllMain执行. 您使用的GdiPlus库似乎从未打算从库中使用.但作为一般规则,在编写库代码时,您应该了解DllMain的限制,并确保您在初始化和完成部分中的代码尊重它.我认为这个GdiPlus库在这方面失败了. 相比之下,看一下Delphi RTL的WinApi.GDIPOBJ单元中的代码: initialization if not IsLibrary then begin // Initialize StartupInput structure StartupInput.DebugEventCallback := nil; StartupInput.SuppressBackgroundThread := False; StartupInput.SuppressExternalCodecs := False; StartupInput.GdiplusVersion := 1; GdiplusStartup(gdiplusToken,@StartupInput,nil); end; finalization if not IsLibrary then begin if Assigned(GenericSansSerifFontFamily) then GenericSansSerifFontFamily.Free; if Assigned(GenericSerifFontFamily) then GenericSerifFontFamily.Free; if Assigned(GenericMonospaceFontFamily) then GenericMonospaceFontFamily.Free; if Assigned(GenericTypographicStringFormatBuffer) then GenericTypographicStringFormatBuffer.free; if Assigned(GenericDefaultStringFormatBuffer) then GenericDefaultStringFormatBuffer.Free; GdiplusShutdown(gdiplusToken); end; 此代码通过确保它不从DllMain调用GdiplusStartup和GdiplusShutdown来遵守规则.相反,它留给使用WinApi.GDIPOBJ的任何库的作者的责任,以确保在适当的时间调用GdiplusStartup和GdiplusShutdown. 如果我是你,我会选择上面列出的三个项目符号选项之一.这些选项中的第三个不太实用,但前两个是不错的选择.如果是我,我会选择第一个选项并修改GdiPlus库中的初始化和终结代码,使其看起来更像WinApi.GDIPOBJ中的代码. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |