我正在使用此示例后面的Qt / MFC迁移框架工具: http://doc.qt.nokia.com/solutions/4/qtwinmigrate/winmigrate-qt-dll-example.html
我构建的DLL由第三方基于MFC的应用程序加载。第三方应用程序基本上调用我的一个导出的DLL函数来启动我的插件和另一个函数来关闭我的应用程序。目前我在关机功能中什么也没做。
当我在第三方应用程序中加载我的DLL时,调用启动函数并且我的DLL成功启动,我可以看到我的消息框。但是,如果我关闭我的插件,然后尝试再次启动它,我会收到以下错误:
Debug Error!
Program: <my 3rd party app>
Module: 4.7.1
File: global\qglobal.cpp
Line: 2262
ASSERT failure in QWidget: "Widgets must be created in the GUI
thread.", file kernel\qwidget.cpp line 1233
(Press Retry to debug the application)
Abort Retry Ignore
这让我觉得我没有做些什么来正确关闭我的插件。我需要做什么才能正确关闭它?
更新: http://doc.qt.nokia.com/solutions/4/qtwinmigrate/winmigrate-walkthrough.html说:
DLL还必须确保它 可以与其他Qt一起加载 基于同一进程的DLL(in 这是QApplication对象的情况 可能已经存在了),那个 创建QApplication的DLL 对象仍然在内存中加载 避免使用内存的其他DLL 该流程不再可用。
所以我想知道是否存在某些问题我需要以某种方式保持原始DLL无论如何加载?
答案 0 :(得分:1)
我知道这个工作!在经历了许多令人沮丧的工作后,我开始工作了。我使用的是Qt / MFC迁移文档中提供的代码:
BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason,
LPVOID /*lpvReserved*/ )
{
static bool ownApplication = FALSE;
if ( dwReason == DLL_PROCESS_ATTACH )
ownApplication = QMfcApp::pluginInstance( hInstance );
if ( dwReason == DLL_PROCESS_DETACH && ownApplication )
delete qApp;
return TRUE;
}
此结构适用于我的插件DLL的单个加载,但在后续加载时失败。我不相信DllMain是调用pluginInstance的正确位置(至少对我的用例来说)。我认为问题是我的第三方应用程序只调用DllMain一次,并且在应用程序退出之前不会卸载DLL。因此,当我启动插件然后将其关闭然后再次启动时,通过调用pluginInstance初始化的QApplication仍然存在。我认为我的第三方应用程序每次启动插件时都会启动单独的线程,所以当我第二次启动插件时它是一个新线程但仍尝试使用DllMain中的原始QApplication设置(DLL仍在加载)。因此我的错误是因为它是尝试写入GUI的新线程。
我正在构建的第三方MFC应用程序需要在我的DLL,Startup()和Shutdown()中进行两次导出,并在相关时间调用它。
因此,我没有按照演练的建议进行操作,而是执行以下操作(伪代码):
extern "C" __declspec(dllexport) void Startup()
{
QMfcApp::pluginInstance( 3rdPartyApp::GetPluginHandle() );
QWinWidget win( 3rdPartyApp::GetParentWindow() );
win.showCentered();
QMessageBox::about( &win, "About", "Hello World" );
}
extern "C" __declspec(dllexport) void Shutdown()
{
qApp->quit();
delete qApp;
}
这对于单个插件来说很好,但是如果我创建多个插件,我不确定这会有多好,因为事件循环集成我觉得应该只有一个QApplication跨所有插件(基于我的阅读) Qt / MFC文件)。
答案 1 :(得分:0)
据我所知,当你加载Qt DLL时,基于MFC的应用程序隐式加载与Qt框架相关的DLL。此外,当您在Dll中启动QApplication时,它只生成一个QApplication实例。但是,当您关闭QApplication时,与Qt框架相关的Dll不会从基于MFC的应用程序中卸载。其中一个DLL永久有QApplication实例。最佳解决方案是可执行文件而不是Dll。