gpt4 book ai didi

c++ - 从 dll 启动 Qt GUI(在 DLLStart 函数中)

转载 作者:可可西里 更新时间:2023-11-01 16:31:22 25 4
gpt4 key购买 nike

我必须从公开 DLLStartDLLStop 的 dll 启动 Qt GUI。 main 中的正常 (.exe) 方法如下:

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

问题是阻塞 a.exec() 调用,因为在 dll 中 DLLStart 需要立即返回(见下文)。有什么解决方法吗?备注:问题与“Adding a Qt GUI to a Dynamic Library”有一些共同点,但不是完全相同的问题。

/** 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) { }

最佳答案

一种适用于 Windows 的方法是在单独的 QThread 中启动 QApplication。它不可移植——它不能在 OS X 上运行(我正在研究修复)。

但是,您不需要单独的线程。如果您将代码注入(inject)到正在运行的应用程序中,它已经有一个事件循环。您只需要创建一个全局 QApplication 对象就可以了。事件循环已经在运行,因此您无需调用 exec()。 Qt 的窗口与 native 事件循环集成,在这方面一切都很好。

do need调用一次 QCoreApplication::processEvents。它将当前应用程序实例集成到 Windows 事件循环中,仅此而已。

因此,您的启动代码可能如下所示:

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;
}

startup()shutdown() 应该在适当的时候调用(在进程附加和分离时)。


旧答案如下。这不再是完全最新的了。

下面是一个简短的示例,有关完整的独立示例,请参阅我的 other answer .

它不可移植,这就是 Qt 文档建议不要使用它的原因。它在 Windows 上工作得很好。主线程并不神奇——在 Windows 上不是。 OS X 上的 Cocoa 在某种程度上是笨拙的,并且使它变得不可能,显然 :(。

请注意,如果加载 DLL 的应用程序已经使用 Qt,那么您无需再做任何事情。确保使用相同的 C++ 编译器编译 DLL,链接相同的 C++ 运行时,并使用与应用程序所用版本二进制兼容的 Qt 版本。然后您就不需要您自己的 QApplication 实例。为了完成一些有用的工作,显示一个 Widget 或实例化一些带有计时器的 QObjects,这将使它们变得忙碌。您还可以使用 QMetaObject::invokeMethod(obj, "mySlot", Qt::QueuedConnection) 而不是使用计时器:当控制返回到事件循环时将进行调用。

如果那不可能,那么下面是您唯一的选择。据我所知,工作得很好。

请注意,我在这里有点讽刺:如果您是使用 DLL 的应用程序的作者,则可能会可靠地满足上一段中的条件。否则——算了吧。

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

关于c++ - 从 dll 启动 Qt GUI(在 DLLStart 函数中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11054087/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com