运行windeployqt后找不到平台插件DLL

时间:2019-02-18 08:43:06

标签: qt qt-quick vst windeployqt

我正在使用独立的exe文件单独制作VST音频插件,它们都共享大部分代码,并且试图使用Qt Quick创建弹出窗口。

一开始,我将Qt DLL从安装的bin文件夹复制到了二进制文件的文件夹中,但是pluginsqml复制了任何内容夹。弹出窗口在exe版本中可以正常工作;但是对于VST版本,它声称QtQuick.Controls的DLL无法加载。下面是Visual Studio的一些调试输出:

“vsthost.exe”(Win32): 已加载“D:\development\Qt\5.10.1\msvc2017_64\qml\QtQuick\Controls.2\qtquickcontrols2plugind.dll”。已加载符号。
“vsthost.exe”(Win32): 已卸载“D:\development\Qt\5.10.1\msvc2017_64\qml\QtQuick\Controls.2\qtquickcontrols2plugind.dll”
file:///D:/my_project_folder/ParamPopForm.ui.qml:2:1: plugin cannot be loaded for module "QtQuick.Controls": Cannot load library D:\development\Qt\5.10.1\msvc2017_64\qml\QtQuick\Controls.2\qtquickcontrols2plugind.dll: (some messy broken characters)
     import QtQuick.Controls 2.3 
     ^
windows\dwm\dwmapi\attribute.cpp(92)\dwmapi.dll!00007FFC62FC594E: (caller: 00007FFC62D8071A) ReturnHr(31) tid(79c) 80070006 句柄无效。
windows\dwm\dwmapi\attribute.cpp(92)\dwmapi.dll!00007FFC62FC594E: (caller: 00007FFC62D8071A) ReturnHr(32) tid(79c) 80070006 句柄无效。
windows\dwm\dwmapi\attribute.cpp(92)\dwmapi.dll!00007FFC62FC594E: (caller: 00007FFC62D8071A) ReturnHr(33) tid(79c) 80070006 句柄无效。
windows\dwm\dwmapi\attribute.cpp(92)\dwmapi.dll!00007FFC62FC594E: (caller: 00007FFC62D8071A) ReturnHr(34) tid(79c) 80070006 句柄无效。
windows\dwm\dwmapi\attribute.cpp(92)\dwmapi.dll!00007FFC62FC594E: (caller: 00007FFC62D8071A) ReturnHr(35) tid(79c) 80070006 句柄无效。
windows\dwm\dwmapi\attribute.cpp(92)\dwmapi.dll!00007FFC62FC594E: (caller: 00007FFC62D8071A) ReturnHr(36) tid(79c) 80070006 句柄无效。

奇怪的是,DLL已经被加载了,但是突然被卸载了

经过一番努力,我发现windeployqt会收集运行Qt程序所需的所有内容。然后我用以下命令运行它:

D:\development\Qt\5.10.1\msvc2017_64\bin\windeployqt.exe -qmldir D:\projects\my_dir_containing_qml_file MyVstPlugin.dll

此操作之后,情况变得更糟:现在exe和VST都找不到平台DLL。但是我可以看到平台DLL文件位于platforms/qwindowsd.dll中,与其他收集的Qt DLL文件位于同一目录中。

此外,我发现Qt5Cored.dll已被windeployqt修改,因为它的修改时间已更改。我找到了一个选项--no-patchqt,用于不修补Qt5Core库。修补程序是用来做什么的?

1 个答案:

答案 0 :(得分:0)

研究Qt源代码后,我在创建Qt对象之前通过添加搜索路径部分解决了该问题。

在每个库路径的 platforms 子目录中搜索平台DLL,在 qfactoryloader.cpp 中的QFactoryLoader::update()方法中引用平台DLL,并在{{1 }}在 qplatformintegrationfactory.cpp 的开头。 Qt系统将使用当前工作目录填充库路径。但是,根本没有引用包含您的DLL的目录。因此,在创建任何内容之前,必须将其输入Qt系统。

当我们使用JUCE开发VST时,可以通过以下方式添加DLL的路径:

Q_GLOBAL_STATIC_WITH_ARGS

此外,您还必须将其提供给QML库搜索路径:

QCoreApplication::addLibraryPath( juce::File::getSpecialLocation( juce::File::currentExecutableFile ).getParentDirectory().getFullPathName().toRawUTF8() );
app = new QGuiApplication( argc, argv );

但是,这仍然不能解决突然卸载window = new QQuickView; window->engine()->addPluginPath( juce::File::getSpecialLocation( juce::File::currentExecutableFile ).getParentDirectory().getFullPathName().toRawUTF8() ); window->engine()->addImportPath( juce::File::getSpecialLocation( juce::File::currentExecutableFile ).getParentDirectory().getFullPathName().toRawUTF8() ); window->setGeometry( 100, 100, 400, 650 ); window->setSource( QUrl::fromLocalFile( WOL_SOURCE_DIR "/src/GUI/ParamPopForm.ui.qml" ) ); window->show(); DLL的失败,它可能有“更深层的”原因。