How to create a Qt shared library for a non-Qt app

2019-02-17 21:01发布

问题:

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.

回答1:

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.



回答2:

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.



回答3:

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.