c++

动态库灵活导入导出(windows,Unix 适配)

by nineone, 2023-05-24


#ifdef API_EXPORTS
#if defined(_MSC_VER)
#define API __declspec(dllexport)
#else
#define API __attribute__((visibility("default")))
#endif
#else
    
#if defined(_MSC_VER)
#define API __declspec(dllimport)
#else
#define API
#endif
#endif

这段代码使用预处理器指令(#ifdef,#if等)定义了API宏。该宏的定义取决于是否定义了API_EXPORTS。
如果定义了API_EXPORTS,表示当前是导出库(.dll或.so),API宏定义为:

  • 在Windows下为__declspec(dllexport),表示导出符号。
  • 在其他系统下为__attribute__((visibility("default"))),也表示导出符号。
    如果未定义API_EXPORTS,表示正在导入库,API宏定义为:
  • 在Windows下为__declspec(dllimport),表示导入符号。
  • 在其他系统下为空,表示普通符号。
    这样,在编译导出库时定义API_EXPORTS,那么API宏就代表导出,在其修饰的方法或类前加上该宏,以导出其符号。
    而在编译导入库时,不定义API_EXPORTS,那么API宏就代表导入,修饰方法或类表示导入其符号。
    这段代码一般出现在导出导入库的头文件中。在实现文件中,根据是否导出而定义或者不定义API_EXPORTS,来控制API宏的定义。
    该机制可以很好地用于Windows下的DLL导出导入,以及类Unix系统下的SO导出导入。
    所以,总结来说,这段代码实现了一个双重宏(double macro)API,其定义取决于是否定义API_EXPORTS:
  • 定义时,表示导出库,API用于导出符号。
  • 未定义时,表示导入库,API用于导入符号。
    这是一种非常常用的导出导入控制机制,利用预处理器灵活地为不同目的定义宏。
    理解预处理器以及导出导入机制对开发可重用的库至关重要。如果在理解和使用该机制的过程中有任何疑问,也请在评论中提出,我将进行详细的解释和总结。
    在实现文件中定义或者不定义API_EXPORTS,并利用API宏修饰要导出/导入的方法和类,应可以成功编译导出和导入两个库。
c++

作者: nineone

2025 © typecho & elise 17 ms