Using a Qt-based DLL in a non-Qt application

Viewed 13663

Am I doing it right?

A client of mine has a group where I'm developing Qt-based client-server stuff with a lot of fun widget stuff and sockets.

Another group within the company wants to use a wrapped version of the QTcpSocket-based client data provider classes. (Which does basically what it sounds like, provides data from the server to the client displays)

However, that group has a huge application built mostly with MFC, and that is simply not going to change any time soon. The Qt-based DLL is also delay-loading so that it can be deployed without this feature in certain configurations.

I've got it working, but it's a little hacky. Here's my solution at the moment:

The DLL wrapper class constructor calls QCoreApplication::instance() to see if it's NULL or not. If it's NULL, it assumes it's in a non-Qt app, and creates a QCoreApplication instance of it's own:

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

It then will set up a windows timer to occasionally call 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);
}

The callback simply calls the processEvents() function using the timerID as a pointer to the class instance. The SetTimer() docs say when HWND is NULL it ignores the timerID, so this appears to be perfectly valid.

VOID CALLBACK BLAHBLAH_TimerCallback(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
    ((BLAHBLAH*)idEvent)->processEvents(); // basically just calls d->_app->processEvents();
}

I then destroy the QCoreApplication instance as the very last thing in the destructor.

BLAHBLAH::~BLAHBLAH()
{
    .. other stuff

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

If the hosting application wishes to time the calls to processEvents() itself, it can pass 0 in for eventTimerInterval and call BLAHBLAH::processEvents() itself.

Any thoughts on this? Porting that app to Qt is not an option. It's not ours.

It appears to work, but there are probably several assumptions being broken here. Can I just construct a QCoreApplication with dummy arguments like that? Is the event queue safe to operate in this manner?

I don't want this blowing up in my face later. Thoughts?

2 Answers
Related