0

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

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

“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 库的选项。补丁是干什么用的?

4

1 回答 1

0

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

平台 DLL在每个库路径的平台QFactoryLoader::update()子目录中搜索,在 qfactoryloader.cpp 的方法中引用,在qplatformintegrationfactory.cppQ_GLOBAL_STATIC_WITH_ARGS的开头实例。Qt 系统将使用当前工作目录填充库路径。但是,根本不引用包含您的 DLL 的目录。所以你必须在创建任何东西之前将它提供给 Qt 系统。

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

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

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

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();

但是,这仍然没有解决突然卸载QtQuick.ControlsDLL的失败,它可能有“更深层次”的原因。

于 2019-02-20T05:51:16.590 回答