如何为非Qt应用程序创建一个Qt共享库

8
我已经开发了一个包含Qt共享库和Qt应用程序的应用。Qt共享库导出一个带有几个信号的单一类。我使用了Q_DECL_EXPORT / Q_DECL_IMPORT宏来实现这一点。现在dll和应用程序之间的通信是通过Qt信号和插槽进行的,这需要使用QObject开发应用程序。
现在我被要求将Qt共享库制作为一个理想的DLL,客户端应用程序不依赖于Qt框架。
我看到了以下帖子 Using a Qt-based DLL in a non-Qt application ,但不确定是否这是最佳方法。
请问有什么可能的选项可以开发Qt共享库以在非Qt应用程序中使用?

2
听起来你要创建一个使用Qt作为后台的API接口。根据我的经验,你需要小心不要在任何头文件中包含与Qt相关的内容,这些头文件将被你的DLL的最终用户使用。因此,你需要仔细地在.cpp文件中进行所有前向声明和头文件的包含。 - Son-Huy Pham
1
Huytard - 感谢指点。听起来是个不错的方法。将Qt功能限制在库内,并导出少量非Qt函数以供应用程序接口。 - Rak
3个回答

4

在库中,您可以在新线程中创建QCoreApplication实例。您应该检查只创建一个实例,因为每个Qt应用程序应该只包含一个QCoreApplication

所以您的库可以像这样:

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();
   }
}  

这样一来,您即可在非Qt应用程序中使用您的Qt共享库。


1
我猜你需要使用静态链接与Qt库。这要求你获取或创建一个静态的Qt库构建,然后使用它来编译你的共享库。

抱歉,我没有理解重点。在为非Qt应用程序创建Qt库时,这有什么用处呢?它是否仍然使用Qt信号和插槽来与Qt库进行接口交互? - Rak
如果你想在你的库中使用Qt,你需要使用Qt构建它。这有什么令人惊讶的呢?当然它仍然会使用Qt信号和槽与Qt库进行接口交互。否则它怎么能工作呢?但是你的库将在没有Qt DLLs的情况下工作,使用你的库的应用程序也将如此。 - Pavel Strakhov
谢谢Riateche。但我不希望Qt应用程序依赖于使用Qt信号和槽。 - Rak

0

我刚刚解决了同样的问题,并且能够在一个非Qt(Delphi)应用程序中加载和调用一个完全封装在DLL(Qt 5.8)中的QApplication。

我遵循了@Nejat的代码示例。但是这对我没有起作用,该线程中的任何Qt GUI都被显示,但被阻塞了。

我无法使用QApplication::processEvents()解决此问题,我认为这与QThread有冲突。

解决方案不是使用QThread来创建QApplication,而是使用Win32的CreateThread函数并创建一个“非qt”线程。因此,也没有必要将SharedLibrary设置为QObject。


1
你能否请发布一下你的解决方案? - Eugene Kolesnikov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接