gpt4 book ai didi

qt - 在非 Qt 应用程序中使用基于 Qt 的 DLL

转载 作者:行者123 更新时间:2023-12-03 11:02:34 24 4
gpt4 key购买 nike

我做得对吗?

我的一个客户有一个小组,在那里我正在开发基于 Qt 的客户端 - 服务器的东西,其中包含许多有趣的小部件和套接字。

公司内的另一个小组想要使用基于 QTcpSocket 的客户端数据提供程序类的包装版本。 (这基本上就是它听起来的样子,从服务器向客户端显示提供数据)

但是,该小组有一个主要使用 MFC 构建的庞大应用程序,而且这种情况不会很快改变。基于 Qt 的 DLL 也是延迟加载的,因此它可以在某些配置中没有此功能的情况下进行部署。

我已经让它工作了,但它有点hacky。这是我目前的解决方案:

DLL 包装类构造函数调用 QCoreApplication::instance() 来查看它是否为 NULL。如果它是 NULL,它假定它在一个非 Qt 应用程序中,并创建它自己的 QCoreApplication 实例:

if (QCoreApplication::instance() == NULL)
{
int argc = 1;
char* argv[] = { "dummy.exe", NULL };
d->_app = new QCoreApplication(argc, argv); // safe?
}
else
d->_app = NULL;

然后它会设置一个 Windows 计时器来偶尔调用 processEvents():
if (eventTimerInterval > 0)
{
// STATE: start a timer to occasionally process the Qt events in the event queue
SetTimer(NULL, (UINT_PTR)this, eventTimerInterval, CDatabaseLayer_TimerCallback);
}

回调只是使用 timerID 作为指向类实例的指针来调用 processEvents() 函数。 SetTimer() 文档说,当 HWND 为 NULL 时,它会忽略 timerID,因此这似乎是完全有效的。
VOID CALLBACK BLAHBLAH_TimerCallback(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
((BLAHBLAH*)idEvent)->processEvents(); // basically just calls d->_app->processEvents();
}

然后我销毁 QCoreApplication 实例作为析构函数中的最后一件事。
BLAHBLAH::~BLAHBLAH()
{
.. other stuff

QCoreApplication* app = d->_app;
d->_app = NULL;
delete d;
if (app != NULL)
delete app;
}

如果宿主应用程序希望自己对 processEvents() 的调用计时,它可以为 eventTimerInterval 传递 0 并调用 BLAHBLAH::processEvents() 本身。

对此有何想法?将该应用程序移植到 Qt 不是一种选择。这不是我们的。

它似乎有效,但这里可能有几个假设被打破。我可以用这样的虚拟参数构造一个 QCoreApplication 吗?以这种方式操作事件队列是否安全?

我不想以后这件事在我脸上炸开。想法?

最佳答案

研究 Qt 代码,似乎需要 QCoreApplication 来调度系统范围的消息,例如计时器事件。诸如信号/插槽甚至 QThread 之类的东西不依赖于它,除非它们与那些系统范围的消息相关。这是我在共享库中执行此操作的方法(以跨平台方式使用 Qt 本身)并且我实际上确实调用了 exec,因为 processEvents() 本身并不能处理所有内容。

我有一个全局命名空间:

// Private Qt application
namespace QAppPriv
{
static int argc = 1;
static char * argv[] = {"sharedlib.app", NULL};
static QCoreApplication * pApp = NULL;
static QThread * pThread = NULL;
};

我在 QObject(即 moc'ed)中有一个 OpenApp 方法,如下所示:
// Initialize the app
if (QAppPriv::pThread == NULL)
{
// Separate thread for application thread
QAppPriv::pThread = new QThread();
// Direct connection is mandatory
connect(QAppPriv::pThread, SIGNAL(started()), this, SLOT(OnExec()), Qt::DirectConnection);
QAppPriv::pThread->start();
}

这是 OnExec 插槽:
if (QCoreApplication::instance() == NULL)
{
QAppPriv::pApp = new QCoreApplication(QAppPriv::argc, QAppPriv::argv);
QAppPriv::pApp->exec();
if (QAppPriv::pApp)
delete QAppPriv::pApp;
}

到目前为止,它似乎运行良好,我不确定最后是否需要删除该应用程序,如果我找到了一些东西,我会更新我的答案。

关于qt - 在非 Qt 应用程序中使用基于 Qt 的 DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2150488/

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