【发布时间】:2011-01-10 03:58:17
【问题描述】:
我做得对吗?
我的一个客户有一个小组,我正在开发基于 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 3 显然支持创建插件 dll - 例如用于基于 chrome safari 和 mozilla 的浏览器的 npapi 类型插件。但这似乎已从 Qt 4 中删除。
-
感谢您提出问题!你知道这是否是现在 4.8 中最好的方法,还是有更好的方法。实际上我运行一个单独的 QThread 并在那里创建和执行 QCoreApplication(全局 argc 和 argv)。 QThread本身不需要QCoreApplication,只有一些系统级的消息比如timer需要dispatcher。