C++的动态库与静态库
Dionysen

在C++中,动态库(Dynamic Link Library,DLL)和静态库(Static Library)是两种不同的库文件,它们在程序中的链接方式和运行时行为上有一些重要的异同点。

动态库与静态库的相同点

  1. 库的作用: 无论是动态库还是静态库,它们的目的都是为了将代码模块化,以便在多个程序中共享和重复使用。

  2. 包含编译后的二进制代码: 两者都包含了已经编译好的二进制代码,可以被程序调用。

动态库与静态库不同点

  1. 链接方式

    • 动态库: 在程序运行时动态加载,链接是在运行时进行的。动态库的代码并不在编译时与程序代码直接链接,而是在运行时由操作系统动态加载。
    • 静态库: 在程序编译时被链接到程序中。编译器在编译时将库的代码和程序的代码合并成一个可执行文件。
  2. 文件扩展名

    • 动态库: 通常有不同的扩展名,如.dll(Windows,Dynamic Link Library)或.so(Linux,Shared Object)。
    • 静态库: 通常有不同的扩展名,如.lib(Windows,Library)或.a(Linux,Archive)。
  3. 文件大小

    • 动态库: 通常比静态库小,因为多个程序可以共享一个动态库的实例。
    • 静态库: 通常较大,因为每个使用该库的程序都会包含其完整的副本。
  4. 更新和维护

    • 动态库: 如果动态库的代码发生变化,只需替换动态库文件即可。程序无需重新编译。
    • 静态库: 如果静态库的代码发生变化,必须重新编译并链接使用该库的程序。
  5. 内存使用

    • 动态库: 共享一份内存,因此在系统中只有一个副本。
    • 静态库: 每个使用该库的程序都有其自己的副本,因此可能会占用更多内存。
  6. 移植性

    • 动态库: 更易于实现跨平台的移植,因为动态库可以在不同平台上具有相同的接口。
    • 静态库: 在不同平台上可能需要不同的库文件。

在实际应用中,选择使用动态库还是静态库取决于项目的需求和设计考虑。通常,动态库在共享代码、更新维护和节省内存方面具有优势,而静态库在性能和依赖管理方面可能更有优势。

总结:静态库相当于添加额外的编译单元,直接链接到可执行文件中;而动态库只是将符号链接到可执行文件,当需要调用库的内容时,从动态库文件中调用

不同平台

不同操作系统和硬件架构之间存在差异,导致在编译和链接时产生的二进制代码也有所不同。

不同的操作系统有不同的系统调用、API和二进制接口。一个在Windows上编译的库通常不能直接在Linux上使用,反之亦然。

不同的硬件体系结构(如x86、x86_64、ARM等)具有不同的指令集和内存布局。库中包含的机器代码通常是特定于体系结构的,因此需要为特定体系结构进行编译。

不同的编译器和工具链可能会对代码生成、调试信息等方面有所不同,使用不同的编译器编译的库可能是不兼容的。

代码差异

静态库的代码正常写,可以直接编译链接,而动态库则需要定义哪些需要被导出,不同平台的顶踹方式有所不同。

在Windows平台上使用 __declspec(dllexport)__declspec(dllimport) 来指定导出和导入符号。

在Linux/Unix(MacOS)平台上使用 __attribute__((visibility("default"))) 来指定导出符号。

跨平台使用时,使用宏定义不同平台的导出代码:

#ifdef __WIN32__
#ifdef LIBRARY_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif
#else
#define MY_API __attribute__((visibility("default")))
#endif

// 在动态库中导出符号
class MY_API MyClass {
public:
void myFunction();
};
显示评论