我将问题跟踪到GdiPlus.pas单元终结部分,该部分调用GdiPlusShutdown,它永远不会返回.
如何避免这种僵局?
解决方法GdiplusStartup
功能的文档说明了这一点: Do not call
Require your clIEnts to callGdiplusstartup
orGdiplusShutdown
inDllMain
or in any
function that is called byDllMain
. If you want to create a DLL that
uses GDI+,you should use one of the following techniques to
initialize GDI+:Gdiplusstartup
before they call the functions in your DLL and to callGdiplusShutdown
when they have
finished using your DLL. Export your own startup function that callsGdiplusstartup
and your own shutdown function that callsGdiplusShutdown
. Require your clIEnts
to call your startup function before they call other functions in your
DLL and to call your shutdown function when they have finished using
your DLL. CallGdiplusstartup
andGdiplusShutdown
in each of your functions that make GDI+ calls.
通过将此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中的代码.
总结以上是内存溢出为你收集整理的delphi – 使用GdiPlus卸载DLL时程序挂起全部内容,希望文章能够帮你解决delphi – 使用GdiPlus卸载DLL时程序挂起所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)