如何为非 Qt 应用程序创建 Qt 共享库
Posted
技术标签:
【中文标题】如何为非 Qt 应用程序创建 Qt 共享库【英文标题】:How to create a Qt shared library for a non-Qt application 【发布时间】:2013-06-20 19:52:25 【问题描述】:我开发了一个具有 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 应用程序的可能选项。
【问题讨论】:
听起来您要创建一个在幕后使用 Qt 的 API 接口。根据我的经验,您必须小心不要在任何头文件中包含与 Qt 相关的项目,这些头文件将被您的 DLL 的最终用户使用。因此,您必须小心地进行所有前向声明,并主要在 .cpp 文件中包含标头。 Huytard - 感谢您的指点。听起来是个好方法。将 Qt 功能限制在库中,并导出一些非 Qt 函数供应用程序接口。 【参考方案1】:您可以在库的新线程中创建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 共享库。
【讨论】:
【参考方案2】:我猜你需要使用 Qt 库的静态链接。它要求您获取或创建静态 Qt 库构建,然后使用它来编译您的共享库。
【讨论】:
对不起,我没有明白这一点。这对于为非 Qt 应用程序创建 Qt 库有何用处。它不是仍然使用 Qt 信号和插槽来连接 Qt 库吗? 如果你想在你的库中使用Qt,你需要用Qt来构建它。为什么这令人惊讶?当然,它仍然会使用 Qt 信号和插槽与 Qt 库进行交互。它还能如何工作?但是你的库可以在没有 Qt DLL 的情况下工作,使用你的库的应用程序也是如此。 谢谢里亚切。但我不希望 Qt 应用程序依赖于使用 Qt 信号和插槽。【参考方案3】:我刚刚解决了同样的问题,我能够将 QApplication 完全封装在一个 DLL (Qt 5.8) 中,该 DLL (Qt 5.8) 是从非 Qt (Delphi) 应用程序加载和调用的。
我遵循了@Nejat 的代码示例。但是,这对我不起作用,该线程中的任何 Qt GUI 都显示了,但被阻止了。
我无法使用QApplication::processEvents()
解决此问题,并且我认为与 QThread 存在冲突。
解决方案不是为 QApplication 使用 QThread,而是使用 Win32 CreateThread
函数并创建一个 "non qt" 线程。因此也没有必要让 SharedLibrary 成为 QObject。
【讨论】:
能否请您发布您的解决方案?以上是关于如何为非 Qt 应用程序创建 Qt 共享库的主要内容,如果未能解决你的问题,请参考以下文章