创建共享库
以下部分列出了创建共享库时应注意的某些事项。
使用共享库中的符号
共享库中包含的符号(函数、变量或类)如果要供应用程序或其他库等客户端使用,必须以特殊方式标记。这些符号被称为公共符号,可以导出或公开可见。
其余的符号不应该从外部可见。在大多数平台上,编译器会默认隐藏这些符号。在某些平台上,需要使用特殊的编译器选项来隐藏这些符号。
编译共享库时,必须将其标记为导出。要从客户端使用共享库,某些平台可能还需要特殊的导入声明。
根据目标平台的不同,Qt 提供了包含必要定义的特殊宏:
- Q_DECL_EXPORT 必须添加到编译共享库时使用的符号声明中。
- Q_DECL_IMPORT 必须添加到编译使用共享库的客户端时所用符号的声明中。
现在,我们需要确保调用正确的宏,无论是编译共享库本身,还是编译使用共享库的客户端。通常,可以通过添加一个特殊的头文件来解决这个问题。
假设我们要创建一个名为mysharedlib 的共享库。该库的特殊头文件mysharedlib_global.h
是这样的:
#include <QtCore/QtGlobal> #if defined(MYSHAREDLIB_LIBRARY) # define MYSHAREDLIB_EXPORT Q_DECL_EXPORT #else # define MYSHAREDLIB_EXPORT Q_DECL_IMPORT #endif
在该库的每个头文件中,我们都指定了以下内容:
#include "mysharedlib_global.h" MYSHAREDLIB_EXPORT void foo(); class MYSHAREDLIB_EXPORT MyClass...
然后,我们需要确保在编译库时为编译器定义MYSHAREDLIB_LIBRARY
。这需要在库的构建系统中完成。如果使用CMake,我们将增强共享库目标:
target_compile_definitions(mysharedlib PRIVATE MYSHAREDLIB_LIBRARY)
如果使用qmake,则在共享库的
DEFINES += MYSHAREDLIB_LIBRARY
添加到共享库的.pro
文件中。
注: 在 Qt Creator和Qt VS Tools中的库向导为您提供了一个骨架,可为您设置这些事项。
头文件注意事项
通常情况下,客户端只包含共享库的公共头文件。这些库在部署时可能会安装在不同的位置。因此,必须排除构建共享库时使用的其他内部头文件。
例如,库可能会提供一个封装硬件设备的类,其中包含一个由第三方库提供的设备句柄:
#include <footronics/device.h> class MyDevice { private: FOOTRONICS_DEVICE_HANDLE handle; };
使用聚合或多重继承时,由Qt Widgets Designer 创建的表单也会出现类似情况:
#include "ui_widget.h" class MyWidget : public QWidget { private: Ui::MyWidget m_ui; };
在部署该库时,不应依赖于内部头文件footronics/device.h
或ui_widget.h
。
利用各种 C++ 编程书籍中描述的指针到实现惯用法可以避免这种情况。对于具有值语义的类,可考虑使用QSharedDataPointer 。
二进制兼容性
对于加载共享库的客户端来说,要想正常工作,使用的类的内存布局必须与编译客户端时使用的库版本的内存布局完全一致。换句话说,客户端在运行时找到的库必须与编译时使用的版本二进制兼容。
如果客户端是一个自包含的软件包,能提供所有需要的库,这通常不是问题。
但是,如果客户端应用程序依赖于属于不同安装包或操作系统的共享库,那么我们就需要考虑共享库的版本方案,并决定在哪个级别保持二进制兼容性。例如,主要版本号相同的 Qt 库保证二进制兼容。
保持二进制兼容性对更改类有一些限制。在KDE - Policies/Binary Compatibility Issues With C++ 中可以找到很好的解释。这些问题应该在库设计之初就加以考虑。我们建议尽可能使用信息隐藏原则和指针实现技术。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.