Cannot find platform plugin DLL after running windeployqt

785 Views Asked by At

I am making VST audio plugin alone with a standalone exe, both share most part of code, and I am trying to make a popup window using Qt Quick.

At the very beginning, I copied Qt DLLs from installation's bin folder to the folder of my binaries, but NOT copying anything from plugins and qml folder. The popup window works properly in exe version; but for the VST version, it claims that the DLL for QtQuick.Controls cannot be loaded. Some debug output to Visual Studio is attached below:

“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 句柄无效。

Strangely, the DLL has already been loaded, but suddenly unloaded

After some efforts, I found windeployqt would collect all stuffs you need to run a Qt program. Then I run it with:

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

After this operation, the things got worse: now both exe and VST cannot find platform DLL. However I can see the platform DLL file is just at platforms/qwindowsd.dll, in the same directory of other collected Qt DLL files.

In addition, I found the Qt5Cored.dll is modified by windeployqt, as its mod time is changed. And I found an option --no-patchqt to not patching Qt5Core library. What is the patching used for?

1

There are 1 best solutions below

1
jiandingzhe On

After diving into Qt source code, I partially solved the problem by adding search paths before creating Qt objects.

The platform DLLs are searched in platforms subdirectory in each library path, which is referred in QFactoryLoader::update() method in qfactoryloader.cpp, instanced in Q_GLOBAL_STATIC_WITH_ARGS in beginning of qplatformintegrationfactory.cpp. Qt system would fill library paths with current working directory. However, the directory containing your DLLs is not referred at all. So you have to feed it to Qt system before create anything.

As we are using JUCE to develop VST, the DLL's path can be added by:

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

Also, you have to feed it to QML library search path:

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

However, this still did not solve the failure of sudden unloading QtQuick.Controls DLL, it may have "deeper" reasons.