Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
323 views
in Technique[技术] by (71.8m points)

c++ - Starting Qt GUI from dll (in DLLStart function)

I have to start a Qt GUI from a dll exposing DLLStart and DLLStop. The normal (.exe) approach in main is as follows:

int main(int argc, char *argv[]) {
    QApplication a(argc, argv); Dialog w;
    w.show();
    return a.exec();
}

The problem is the blocking a.exec() call, since in the dll DLLStart needs to return immediately (see below). Any workaround for this? Remark: The question is sharing some common ground with " Adding a Qt GUI to a Dynamic Library ", but it is no exact duplicate.

/** start module  */
int __stdcall DLLStart(void) {
    .. 
    QApplication qaDll(ac, av); Dialog w;
    w.show();
    qaDll.exec();
    return 0; // never reached
}

/** stop module */
void __stdcall DLLStop(void) { }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

One way works on Windows is to start QApplication in a separate QThread. It's not portable -- it doesn't work on OS X (I'm researching a fix).

But, you don't need a separate thread. If you inject your code into a running application, it already has an event loop. You only need to create a global QApplication object and you're done. The event loop is already running, so you don't need to call exec(). Qt's windows integrate with the native event loop, and everything is good on that front.

You do need to call QCoreApplication::processEvents once. It will integrate the current application instance into the windows event loop, and that's it.

Thus, your startup code could look as follows:

static struct Data {
  int argc = 1;
  char *argv[2] = {strdup("dummy"), {}};
  QApplication app{argc, argv};
  MainWindow win;
} *d;

static void startup() {
  d = new Data;
  d->win.show();
  d->app.processEvents();
}

static void shutdown() {
  delete d;
}

The startup() and shutdown() should be called at appropriate times (on process attach and detach).


Old answer follows. This is not completely up to date anymore.

A short example is below, for a complete self-contained example see my other answer.

It is not portable and that's why Qt documentation advises against it. It works just fine on Windows. The main thread is not magic -- not on Windows. Cocoa on OS X is clumsy in a way and makes it impossible, apparently :(.

Note that if the application that loads the DLL already uses Qt, then there's nothing further for you to do. Ensure you compile your DLL with the same C++ compiler, link against the same C++ runtime, and use a version of Qt that's binary compatible with the one used by application. You then don't need your own instance of QApplication. To get some useful work done, show a Widget or instantiate some QObjects with timers that will get them busy. You can also use QMetaObject::invokeMethod(obj, "mySlot", Qt::QueuedConnection) instead of using timers: the call will be made when control returns to the event loop.

If that's not possible, then the below is your only option. Works just fine, as far as I can tell.

Note that I'm a bit sarcastic here: The conditions in the previous paragraph will be met reliably maybe if you are the author of the application that uses the DLL. Otherwise -- forget about it.

class AppThread : public QThread {
  int & argc;
  char ** argv;
  int result;
  void run() {
    QApplication a(argc, argv);
    Dialog d;
    d.show();
    result = a.exec();
  }
public:
  AppThread(int & argc, char ** argv) : argc(argc), argv(argv) {}
  ~AppThread() { quit(); wait(); }
}

extern "C" int __stdcall DLLStart(void) {
  auto *thread = new AppThread(argc, argv);
  thread->start();
  return 0;
}

extern "C" void __stdcall DLLStop(void) {
  delete qApp->thread();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...