卸载所有的qt dlls

3

我有一个包含Qt GUI的dll,由“服务器”应用程序启动,在GUI被杀死(卸载)后仍然运行。

一切都很好,但如果我重新启动GUI,一切就会崩溃。 如果我只运行一次并列出加载的dll,则Qt5Core,Qt5Gui和qwindows.dll永远不会卸载。

我认为我需要卸载它们(我的dll在专用线程中创建一个QApplication,并正确销毁)

我正在使用Windows 7上的msvc2010编译器,没有日志(“通用保护错误”对我来说不是日志)。

有没有办法卸载所有qt dll(Qtcore,QtGui,qwindows)?(不调用“FreeLibrary”函数)


你想在不调用FreeLibrary的情况下卸载.dll文件吗? - Dmitry Sazonov
Qt的dll(Core等)不是显式加载的,我只加载(和释放)自己的dll。 - Loy
因此,如果您想使用 FreeLibrary 卸载 Qt,则需要使用 LoadLibrary 加载它。请阅读有关 DLL 的延迟加载的内容。 - Dmitry Sazonov
这种方式是可行的,但丑陋 :/ 感谢您的帮助 =) - Loy
我尝试过了。但它不能工作,因为我的DLL是由一个中间应用程序启动的,该应用程序被杀死(但并不总是正确,这才是真正的问题,在下午4点解决)。而且,我无法修改“服务器”应用程序。现在它正在工作。 - Loy
显示剩余2条评论
2个回答

1
我最近向Qt公司提交了一个支持工单,关于同样的问题,但是得到了令人失望的回复。有一个有意识的设计决策,即Qt插件要保持加载状态直到应用程序终止。因此,许多为非Qt主机应用程序设计的基于Qt的插件将不得不采取脆弱的解决方案来确保正确运行。
当你卸载各种Qt DLL时,卸载顺序相当重要,因为许多DLL彼此依赖。以下是我从Qt支持工程师那里收到的确切回复:
插件故意不会在应用程序终止之前卸载,因为过去曾经出现过卸载插件的问题,因此达成共识,它们应该在应用程序生命周期内保持加载状态。您应该先卸载插件,然后再卸载自己的dll。插件可以按任何顺序卸载,因为它们彼此不依赖,主要平台插件 - qwindows.dll - 将是处理事件等的主要插件。只要 QApplication 不再运行事件循环,您就可以安全地卸载它。只要在卸载 Qt dlls 之前卸载插件,则插件执行的任何清理都将使用仍加载的 Qt dlls 完成,因此不应导致崩溃。

感谢回复!我的(假设的)解决方案将创建一个独立的进程,用管道或其他方式命令它并杀死“客户端”进程。这很丑陋(实时禁止?),并会创建安全问题,但我找不到其他解决方案... - Loy

0

使用GetModuleHandle("dllname")解决了问题,我获取了句柄并可以使用freelibrary。现在运行良好 =)(但不是真正的“动态”... Qt在调试和发布时使用不同的名称,如果有另一个dll“浮动”,我需要修改代码)

感谢您的帮助!


你能否发布一下你已经卸载的DLL的顺序? - Ohad
对不起,我没有正确解释:对于 PoC,我只是获取所有已加载的 dll,在名称中查找“Qt5”,并尝试在每个模块的 while 循环中调用“freelibrary”(最多循环 10 次)。这种(丑陋的)方法可以在 2 或 3 次卸载和重新加载时工作,但之后操作系统将无法正确释放(并崩溃)。这在部署方面并没有“真正”得到解决... :/ - Loy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接