Qt World Summit: Register Today!

Shared Dynamically Linked C++ Library with QT Signals / QNetworkAccessManager

  • I am developing a shared library for Windows, OSX and Linux using QT. The library is loaded dynamically for each platform.

    QT comes loaded with several really great libraries like QString, QNetwork etc. that I find helpful for my cause. This would require me to include QT libraries to whatever software that uses the shared library, but that's fine.

    So far I have been successful in using QString (easy) but found out that I need to make some HTTP REST-calls. QT have QNetworkAccessManager which would be great to utilize here instead of having to include additional libraries like libcurl.

    However I have big difficulties getting it to work. To use QNetworkAccessManager I need to have QtCoreApplication created for my library. This leads me to some questions I would like some help on:

    1. Could using QtCoreApplication become a problem? All QT libraries are native C++ from my understanding but the shared library I create needs to be fully compatible for each platform.

    2. I have tried to use QtCoreApplication in my library but currently I don't even get the design correct. What is the best way? The HTTP request is quite independant from everything else so would it be possible to create QtCoreApplication everytime a HTTP request is done and then delete it? Or should the library user create it before using the other functions and then delete the QtCoreApplication when the application using the library has ended?

    3. How do I use the QtCoreApplication? I have tried to create it but my test cases just stops when I run eventLoop.exec(). It seems to never stop executing there.

    Any help is veeery appriciated!

  • Moderators

    1. Yes, if your loading app also uses Qt, as there can be only one instance of QCoreApplication in a process. Also remember that Qt is a c++ library and there is no unified c++ ABI so if you want to pass Qt types (like QString) across the library boundary you would have to assure somehow that both the app and the library use the same compiler version and settings (e.g. mixing release/debug or CRT linking method will result in bugs or crashes).

    2. I haven't done that myself so I'm speculating, but I would create a single instance of QCoreApplication (it's a singleton) at the loading of the library and destroy that at the unload. The important decission is if the API you wish to expose should be blocking or asynchronous. If it's blocking then a call to your API would create the QNAM object, start the request and enter an event loop that it would exit when the response arrives. Async becomes much harder, as you would have to create a separate thread in which you would create the QCoreApplication instance and the event loop. But QThread also needs a QCoreApplication so you would need to use some other non-Qt threading solution. It's a hairy business.

    3. The basic usage is

    • create a QCoreApplication (QCA) instance
    • create any other Qt objects (e.g QNAM) you need and for example start the network request
    • connect to the QNAM finished signal
    • call exec() on the QCA instance. This is a blocking function that creates and runs an event loop. This will handle request progressing and delivers signals/events.
    • when finished()signal arrives handle the response and
    • call quit() ( or exit(code) ) on the QCA instance. This will end the event loop (exec) and return to the caller.

Log in to reply