1. 简介
在开发跨平台的共享库(Windows
上的 DLL
,Linux
上的 .so
文件)时,控制符号的可见性是一个重要的概念。Qt
框架提供了 Q_DECL_EXPORT
和 Q_DECL_IMPORT
宏来帮助管理这个过程。本指南将介绍这些概念及其使用方法。
2. 基本概念
2.1 符号可见性
符号:在编程中,符号指的是函数、类、变量等程序元素的名称。可见性:决定一个符号是否可以被库外的代码访问。
2.2 关键宏
Q_DECL_EXPORT
:用于标记应该从库中导出的符号。
Q_DECL_IMPORT
:用于标记应该从库中导入的符号。
3. 工作原理
3.1 Windows
平台
在 Windows 上,Q_DECL_EXPORT 通常被定义为 __declspec(dllexport)。Q_DECL_IMPORT 通常被定义为 __declspec(dllimport)。
3.2 Linux
和其他 UNIX
类平台
在这些平台上,Q_DECL_EXPORT 和 Q_DECL_IMPORT 通常被定义为空。符号可见性通常由其他机制控制,如 GCC 的 -fvisibility 选项。
4. 使用方法
4.1 定义导出宏
通常在头文件中定义一个宏来切换 between 导出和导入:
#if defined(MYLIB_LIBRARY)
# define MYLIB_EXPORT Q_DECL_EXPORT
#else
# define MYLIB_EXPORT Q_DECL_IMPORT
#endif
4.2 使用导出宏
在类或函数声明前使用这个宏:
class MYLIB_EXPORT MyClass {
// ...
};
MYLIB_EXPORT void myFunction();
4.3 编译库
当编译库时,定义 MYLIB_LIBRARY 宏:
add_library(MyLib SHARED ...)
target_compile_definitions(MyLib PRIVATE MYLIB_LIBRARY)
4.4 使用库
当使用库时,不要定义 MYLIB_LIBRARY 宏。只需包含相关的头文件即可。
5. 跨平台考虑
虽然在 Linux 等平台上这些宏可能没有直接效果,但保持这种结构有助于跨平台兼容性。在 Windows 上,使用 Q_DECL_IMPORT 可以提高编译和链接效率。
6. 最佳实践
始终在头文件中使用条件宏定义(如 MYLIB_EXPORT
)。在编译库时定义相应的宏(如 MYLIB_LIBRARY
)。在使用库时,只包含头文件,不要定义库相关的宏。保持一致的命名约定,例如 [LIBNAME]_EXPORT 和 [LIBNAME]_LIBRARY。
7. 结论
理解和正确使用符号可见性机制对于开发高质量的跨平台共享库至关重要。虽然在某些平台上这些宏可能看似多余,但它们为代码提供了良好的结构和跨平台兼容性。
发表回复