库一般分为两种:静态库(.a 、.lib)动态库(.so 、.dll )所谓静态、动态是指链接过程。
特点
静态链接库有两个重大缺点:
- 空间浪费
- 静态链接对程序的更新、部署和发布会带来很多麻烦。一旦程序中有任何模块更新,整个程序就要重新链接,发布给用户。
动态链接库的基本思想:把程序按照模块拆分成各个相对独立的部分,在程序运行时才将它们链接在一起形成一个完整的程序,而不是想静态链接一样把所有的程序模块都链接成一个单独的可执行文件。
特点:
- 代码共享,所有引用该动态库的可执行目标文件共享一份相同的代码与数据。
- 程序升级方便,应用程序不需要重新链接新版本的动态库来升级,理论上只要简单地将旧的目标文件覆盖掉。
-
命名
linux
Linux静态库命名规范,必须是”lib[your_library_name].a”:lib为前缀,中间是静态库名,扩展名为.a。
- 动态链接库的名字形式为 libxxx.so,前缀是lib,后缀名为“.so”。
win
操作系统在可执行文件调用DLL 的内容是才进行加载,可执行文件调用 DLL 的导出函数的方式与函数被静态链接并包含在可执行文件中一样。隐式链接有时称为静态加载(static load)或加载时动态链接(load-time dynamic linking)。
1. 头文件2. 库文件
- 显示链接:只需要库文件即可
操作系统在运行时按需加载 DLL,显式链接 DLL 的可执行文件必须显式加载和卸载 DLL。它还必须设置一个函数指针来访问它从 DLL 中使用的每个函数。与调用静态链接库或隐式链接 DLL 中的函数不同,可执行文件必须通过函数指针调用显式链接 DLL 中的导出函数。显式链接有时称为动态加载(dynamic load)或运行时动态链接(run-time dynamic linking)。
__declspec(dllexport) 加载需要导出的函数名前面导出函数LoadLibrary 加载库,获取模块句柄GetProcAddress 获取函数指针,必须用 typedef 或 using 定义导出函数签名
导入链接库
静态库
动态库
C++ 加载 dll
add.cpp
int add(int x, int y) {std::cout << "Hello, add!" << std::endl;return x + y;}
add.h ```cpp
ifndef ADD_H
define ADD_H
ifdef __cplusplus
extern “C”{
endif
// 导出函数 add() __declspec(dllexport) int add(int x, int y);
ifdef __cplusplus
}
endif
endif //ADD_H
3. 加载 dll 文件
```cpp
// 定义函数指针
typedef int (*FunPtr)(int x, int y);
// Handle to DLL
Handle handle = LoadLibrary("add.dll");
// Function pointer
FunPtr funPtr =(FunPtr) GetProcAddress(handle, "add");
// 调用函数
funPtr(2,3); // 2 + 3;
// 释放载入的动态库
FreeLibrary(handle);
