Requirements: Qt widgets show up when Qt shared lib loads, for none-Qt application.
After some web searching, I found:
All Qt widgets must live in "main thread", the "main thread" is the first Qt object created thread. so, create a none-Qt thread (std::thread), then, create QApplication and some other widgets in that thread should work, but not.
Do not create any Qt related object or call any Qt related static methods before QApplication created, in that none-Qt thread.
The thread solution is not portable for Mac OS, my target platform is Windows only, so, it does not matter.
In my case, if app load my Qt lib, and invoke the method for showing widgets, it works. but for some reason, caller can not call my lib method manually.
If host application (one that loads the shared lib) is Qt application, you should call QApplication::processEvents(), not QApplication::exec(). in my case, I should call QApplication::exec() in that thread.
Source code here:
- dllMain version:
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
auto t = std::thread([]() {
// setCodecForLocale is in the same thread,
// call it before QApplication created should be OK.
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
int i = 0;
int argc = 0;
QApplication app(argc, 0);
auto dialogLogin = new DialogLogin(); // custom widget
dialogLogin->setModal(true);
dialogLogin->show();
app.exec(); // app.processEvents() not work, too.
});
t.join(); // wait for thread ends in dllMain should be BAD, test only
}
return true;
}
- Simple C++ static class version
class LibExecutor {
public:
LibExecutor()
{
auto t = std::thread([]() {
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
int argc = 0;
QApplication app(argc, 0);
auto dialogLogin = new DialogLogin();
dialogLogin->setModal(true);
dialogLogin->show();
app.exec();
});
t.join();
}
};
static LibExecutor libExecutor;
Both version invoke widgets init stuff successfully, but widgets not show up.
Here is how I test it, using Qt load lib, but, event I load lib using Win32 API, failed too.
#include "mainwindow.h"
#include <QApplication>
#include <QLibrary>
int main(int argc, char* argv[])
{
QLibrary lib("F:/lib_location/lib_name.dll");
if (lib.load()) {
qDebug() << "load ok!";
} else {
qDebug() << "load error!";
}
}
DllMain
- see MSDN. – Footling