8

I have developed an application that has Qt shared library and Qt application. Qt shared library exports a single class with few signals in it. I have made use of Q_DECL_EXPORT / Q_DECL_IMPORT macros for this. Right now the communication between the dll and application is through Qt signals and slots and that needs the application to be developed using QObject.

Now I was asked to make Qt shared library as an ideal DLL where Client application doesn't depend on Qt framework.

I saw the following post but Using a Qt-based DLL in a non-Qt application but not sure if that is the best approach.

Could some one please enlighten me with possible options to develop Qt shared library to be used in a non-Qt application.

Community
  • 1
  • 1
Rak
  • 379
  • 6
  • 15
  • 2
    Sounds like you're going to create an API interface that uses Qt behind the scenes. From my experience, you'll have to be careful not to include Qt related items in any header files that will be used end-user of your DLL. So you'd have to carefully make all of your forward declarations and include headers mostly in .cpp files. – Son-Huy Pham Jun 20 '13 at 20:05
  • 1
    Huytard - Thanks for the pointer. Sounds like a good approach. Limit Qt functionality to within the library and export few non Qt functions for the application to interface. – Rak Jun 20 '13 at 20:37

3 Answers3

4

You can create the instance of the QCoreApplication in a new thread in the library. You should check to create only one instance of it, That's because each Qt application should contain only one QCoreApplication.

So your library can be like :

class Q_DECL_EXPORT SharedLibrary :public QObject    
{
Q_OBJECT
public:
    SharedLibrary();

private slots:

    void onStarted();

private:
    static int argc = 1;
    static char * argv[] = {"SharedLibrary", NULL};
    static QCoreApplication * app = NULL;
    static QThread * thread = NULL;
};


SharedLibrary::SharedLibrary()
{
    if (thread == NULL)
    {
        thread = new QThread();
        connect(thread, SIGNAL(started()), this, SLOT(onStarted()), Qt::DirectConnection);
        thread->start();
    }
}
SharedLibrary::onStarted()
{
   if (QCoreApplication::instance() == NULL)
   {
       app = new QCoreApplication(argc, argv);
       app->exec();
   }
}  

This way you can use your Qt shared library even in non Qt applications.

Nejat
  • 31,784
  • 12
  • 106
  • 138
1

I guess you need to use static linkage with Qt library. It requires you to get or create static Qt library build and then use it to compile your shared library.

Pavel Strakhov
  • 39,123
  • 5
  • 88
  • 127
  • Sorry I didn't get the point. How would that be useful in creating Qt library for a non-Qt application. Doesn't it still use Qt signals and slots for interfacing with the Qt library? – Rak Jun 20 '13 at 20:06
  • If you want to use Qt in your library, you need to build it with Qt. Why is that surprising? Of course it will still use Qt signals and slots for interfacing with the Qt library. How else could it work? But your library will work without Qt DLLs, and so will do the application that uses your library. – Pavel Strakhov Jun 20 '13 at 20:14
  • Thanks Riateche. But I don't want the Qt application to depend on using Qt signals and slots. – Rak Jun 20 '13 at 20:39
0

I just resolved the same issue and I'm able to have a QApplication entirely encapsulated in a DLL (Qt 5.8) that is loaded and called from a non-Qt (Delphi) application.

I followed the code sample from @Nejat. However this didn't work for me, any Qt GUI in that thread was shown, but blocked.

I wasn't able to resolve this using QApplication::processEvents() and I assume a conflict with QThread.

The solution was NOT to use a QThread for QApplication but to use the Win32 CreateThread function and create a "non qt" thread. Thus there is also no need to have SharedLibrary to be a QObject.

mayo
  • 3,845
  • 1
  • 32
  • 42