Results 1 to 8 of 8

Thread: How does one use Qt from within a dll ....

  1. #1
    Join Date
    Sep 2011
    Posts
    7
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default How does one use Qt from within a dll ....

    I want write a dll that uses Qt for its UI.

    The 1st requirement is that this dll may be used from any application (ie, a the host may be a Qt, MFC, Win32, Cocoa, whatever-on-whatever platform application).
    The 2nd requirement is that the UI displayed by the dll must run in parallel to the main hosts interface (ie, the dll interface is not "modal" to the main application, and thus it does not block the host application interface itself from running).
    The 3rd requirement is that the dll is statically linked to the Qt libraries.

    Using Qt, my understanding is that you need a QApplication object, and that object should call exec() from the "main thread" which would, in this scenario, exist only in the host application.
    Calling exec would also block the caller - in a standalone application this is fine as it normally called from main() etc. In a dll, this would block the host applications calling thread.

    How does one accomplish this? I have seen similar posts on these forums, but they have never addressed this particular scenario.
    I have achieved these requirements in the past (points 2 and 3 at least) using MFC under Windows, but that is obviously not cross platform!

    Can anyone help me out with a solution please?

    Simon.

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,709
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: How does one use Qt from within a dll ....

    The 3rd requirement is that the dll is statically linked to the Qt libraries.
    That is the solution to Requirement Nr 1, if install Qt as part of installing the DLL is not acceptable.

    The 2nd requirement is that the UI displayed by the dll must run in parallel to the main hosts interface (ie, the dll interface is not "modal" to the main application, and thus it does not block the host application interface itself from running).
    As a side note: this is a VERY broad requirement, and I doubt your solution will be different as to what Qt does internally - that is - implementation per platform/GUI Toolkit, as the platforms/GUI Toolkits are VERY different.

    Using Qt, my understanding is that you need a QApplication object, and that object should call exec() from the "main thread" which would, in this scenario, exist only in the host application.
    Calling exec would also block the caller - in a standalone application this is fine as it normally called from main() etc. In a dll, this would block the host applications calling thread.
    The question is, what exactly is needed.
    If you want to "embed" Qt widgets in windows of other toolkits, such MFC, this will be a real problem.
    If you want to have a "parallel" Qt GUI to the other gui, this is easier, but by no means trivial on the implementation level - but the principals are easy.
    Based on what I just wrote, you can see that your question about blocking the main thread needs to be more specific.

    How does one accomplish this?
    Honestly, you first need to make your requirements more specific/realistic.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  3. #3
    Join Date
    Sep 2011
    Posts
    7
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How does one use Qt from within a dll ....

    OK high_flyer, I'll outline the "requirements" in a programming language agnostic way - I think that will help.

    The dll is essentially used to present the user with an interface to do various things to supplement the main application.
    I want to write the dll purely using Qt.
    I don't know what the host application will be written in.
    The interface presented by the dll needs to run independently from the main application - basically like a modeless dialog in Windows (as opposed to a modal dialog).

    From this point onwards I may be wrong because of my limited knowledge of Qt.
    - To use Qt in my dll to present the interface, I need to have a QApplication object.
    - To use this object, one needs to call exec() on it to run the message pump to make Qt "work".

    The part I cannot work out is: How and when should this be called.

    I hope this clarifies the problem I'm having.

  4. #4
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,709
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: How does one use Qt from within a dll ....

    The interface presented by the dll needs to run independently from the main application - basically like a modeless dialog in Windows (as opposed to a modal dialog).
    Good this makes things much simpler.
    - To use Qt in my dll to present the interface, I need to have a QApplication object.
    Correct.
    - To use this object, one needs to call exec() on it to run the message pump to make Qt "work".
    Correct.
    The part I cannot work out is: How and when should this be called.
    Before any events on the Qt side need to be sent/received.
    Since your Qt part is lives in its own process, the fact you QApplication runs its own event queue is not a problem.
    You can treat your DLL just as it was regular application (exe), which it fact it is, it is just packaged as a DLL.
    Problems occur only if you try to mix the Qt event queue with the event queue of your "host", but as long as they independent, you are on the clear.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  5. #5
    Join Date
    Sep 2011
    Posts
    7
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How does one use Qt from within a dll ....

    Quote Originally Posted by high_flyer View Post
    Good this makes things much simpler.
    Since your Qt part is lives in its own process, the fact you QApplication runs its own event queue is not a problem.
    That sounds good, and what I need to do!

    Quote Originally Posted by high_flyer View Post
    You can treat your DLL just as it was regular application (exe), which it fact it is, it is just packaged as a DLL.
    Again, this sounds exactly how I'd like it to work.

    Quote Originally Posted by high_flyer View Post
    Problems occur only if you try to mix the Qt event queue with the event queue of your "host", but as long as they independent, you are on the clear.
    They will never "mix". All communication is done through a very simple (and thin) function exported from the dll - custom "commands" that are interpreted by the dll as needed. Thus the host application will run its event queue, and the dll will run its own in within its own QApplication.

    Thanks high_flyer - I think I can now start to see a the light at the end of the tunnel

    I have been experimenting around and have come up with a solution that *seems* to be working and fits what you have said. My worry is just if it is the right way of going about it.

    I create a thread (derived from qthread) that is used purely to create and exec my QApplication. When the QApplication quits, this thread exits too.
    I then use the signal/slot mechanism with the QueuedConnection flag to send messages over to the QApplication from the dll function as needed.
    I can call back out of the QApplication to a passed function pointer from the host app as needed too (the host just needs to know that these calls will not come from their main thread, but that's just details).

    With these things in place, it does seem to work.
    But (why is there always a but!) when my host application quits I get a tonne of memory leaks.

    The simplest case is that if I just create a QThread derived class on the heap in the dll when it's loaded, and don't even call start on it, when the dll is unloaded memory allocated in the QThread constructor (QThreadData::current() where it allocates the threadData to be precise) is not deleted.

    As a side note, my QApplication class is created as a local variable in the threads run() call in case this makes any difference.

    Am I missing some sort of global clean-up call that one needs when using Qt in a DLL like this? I thought the memory allocated in the QThreads was reference counted and deleted automatically.

  6. #6
    Join Date
    Oct 2009
    Posts
    483
    Thanked 96 Times in 93 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How does one use Qt from within a dll ....

    I might be wrong, but I doubt Qt is supposed to be used this way. QApplication (or QCoreApplication) may need exclusive access to process-wide resources (such as intercepting events from the OS and window system) that are already controlled by the host application. Executing a QApplication in a QThread is probably a dangerous thing to do with unspecified behaviour.

    I suggest that the Qt GUI be run in a separate process by the DLL, using any IPC mechanism to relay messages between the GUI and the DLL. Of course you will not be able to ship everything as a single nice DLL file.

  7. #7
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,709
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: How does one use Qt from within a dll ....

    QApplication (or QCoreApplication) may need exclusive access to process-wide resources (such as intercepting events from the OS and window system) that are already controlled by the host application.
    Agreed.
    I probably was not very clear on it, when I wrote:
    Since your Qt part is lives in its own process, the fact you QApplication runs its own event queue is not a problem.
    I did mean process, and not thread.

    The simplest case is that if I just create a QThread derived class on the heap in the dll when it's loaded, and don't even call start on it, when the dll is unloaded memory allocated in the QThread constructor (QThreadData::current() where it allocates the threadData to be precise) is not deleted.
    You need to add clean up code in your DLL for when it is unloaded.
    Am I missing some sort of global clean-up call that one needs when using Qt in a DLL like this? I thought the memory allocated in the QThreads was reference counted and deleted automatically.
    The way you said that I am not sure I follow.
    QThread is NOT one of the Qt shared memory classes:
    http://doc.qt.nokia.com/stable/shared.html
    And even if it was, it has nothing to do with the need to delete allocated objects.
    The implicit sharing only means, no copies (allocation) is made when there is no need for it.
    In addition, any QObject you allocate with 'new' and don't give it a parent, you have to delete it your self.
    Is this what you meant in your question?

    As a side note, my QApplication class is created as a local variable in the threads run() call in case this makes any difference.
    This is implementation issue, not an issue of the fact you are running a Qt application in its own process.
    The poster above me answered that, and I agree with it.
    You have to have your DLL start its own process, then you don't need to start QApplication in a thread, which is not a good idea.

    But now that I think of it, if the Qt part and the host part are so independent, why bother with a dll, and not have the Qt part in an exe, which you start from the host?
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  8. #8
    Join Date
    Sep 2011
    Posts
    7
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How does one use Qt from within a dll ....

    Just to conclude my findings regarding this thread, I have had to create a separate executable and start this new process & communicate with it via a stub dll and shared memory.

    I don't actually find this a suitable solution, but it appears like the only "official" way using Qt.

    As it happens I did have a QApplication running on a non-main thread (the thread it was on was created by the dll). Under Windows it all seemed to be working just fine, but the official line is that this sort of usage (ie, QApplication not being created on the executables main thread) is undefined as on some platforms it may lead to odd GUI behaviour. By odd behaviour I think this means the GUI may not respond as expected. I didn't follow my experiments over to OSX and Linux, so I cannot comment further - in hindsight I think I should have just to see what happens.

    So not a neat solution in the end, but I'll just have to live with it

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.