|
@@ -0,0 +1,208 @@ |
|
|
|
|
|
# 库相关知识点 |
|
|
|
|
|
## 静态库 |
|
|
|
|
|
|
|
|
|
|
|
### 1.1基本概念 |
|
|
|
|
|
|
|
|
|
|
|
> 后缀(.lib .a),是一个包含编译好的目标文件(.obj/.o 文件)的归档文件包。 |
|
|
|
|
|
> |
|
|
|
|
|
> **编译时链接**: 关键特征在于它是在程序编译和链接阶段被处理的 |
|
|
|
|
|
> |
|
|
|
|
|
> 程序(.exe/另一个库)链接静态库时,----->扫描静态库找`.obj/.o` 文件----->提取合并到最终程序或目标库 |
|
|
|
|
|
|
|
|
|
|
|
* 直接包含头文件,链接文件 |
|
|
|
|
|
|
|
|
|
|
|
* 不需要复杂的加载或依赖 |
|
|
|
|
|
|
|
|
|
|
|
### 1.2静态库生成 |
|
|
|
|
|
|
|
|
|
|
|
1. 新建项目--选择静态库--创建项目 |
|
|
|
|
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
|
|
|
|
2. 创建.c和.h文件 |
|
|
|
|
|
|
|
|
|
|
|
3. 点击生成解决方案 |
|
|
|
|
|
|
|
|
|
|
|
4. 生成文件 |
|
|
|
|
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
|
|
|
|
### 1.3静态库的调用 |
|
|
|
|
|
|
|
|
|
|
|
1. 新建项目---选择控制台应用---配置创建 |
|
|
|
|
|
|
|
|
|
|
|
2. 右键项目--添加--添加引用 |
|
|
|
|
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
|
|
|
|
3. 引用.h文件--所有配置--所有平台--配置c/c++常规----附加包含添加目录 |
|
|
|
|
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
|
|
|
|
4. 就可以使用引入的库了 |
|
|
|
|
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
|
|
|
|
· 在代码中语句加载lib调用 |
|
|
|
|
|
|
|
|
|
|
|
#### 链接使用静态库(都可以在附加目录中添加路径) |
|
|
|
|
|
|
|
|
|
|
|
1. 需要将.lib链接到主程序 |
|
|
|
|
|
|
|
|
|
|
|
`#pragma comment(lib,"lib/StaticLib1.lib")` |
|
|
|
|
|
|
|
|
|
|
|
2. 添加.h文件 |
|
|
|
|
|
|
|
|
|
|
|
~~~ cpp |
|
|
|
|
|
#pragma comment(lib,"lib/StaticLib1.lib") |
|
|
|
|
|
#include "externalUse.h" //必须包含头文件 |
|
|
|
|
|
~~~ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**项目依赖**作用是确保在构建主项目时先构建依赖项目(控制编译顺序), |
|
|
|
|
|
|
|
|
|
|
|
**项目引用**主项目不仅知道依赖,还会自动链接 `.lib` 文件(控制链接阶段) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 动态库 |
|
|
|
|
|
|
|
|
|
|
|
### 2.1 概念 |
|
|
|
|
|
|
|
|
|
|
|
> DLL 是一种**共享库机制**(Dynamic Link Library),本质上是包含**可执行代码和数据**的二进制文件(`.dll` 后缀)。不同于程序主文件(EXE),它本身不能独立运行(`DllMain` 是初始化的入口点),必须由 EXE 或 其他 DLL 在**运行时动态加载和调用**。 |
|
|
|
|
|
|
|
|
|
|
|
* 作用代码复用减少冗余 |
|
|
|
|
|
* 模块开发,节省内存,资源封装共享,拓展内容 |
|
|
|
|
|
|
|
|
|
|
|
### 2.2 生成 |
|
|
|
|
|
|
|
|
|
|
|
1. 新建项目-->选择动态链接库——>项目配置创建 |
|
|
|
|
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
|
|
|
|
2. 添加头文件和源文件 --->添加预处理定义设置 |
|
|
|
|
|
|
|
|
|
|
|
~~~ cpp |
|
|
|
|
|
#pragma once |
|
|
|
|
|
#define DLL_API |
|
|
|
|
|
#ifdef DLL_API |
|
|
|
|
|
#define DLL_API __declspec(dllexport) |
|
|
|
|
|
#else |
|
|
|
|
|
#define DLL_API __declspec(dllimport) |
|
|
|
|
|
#endif // DLL_API |
|
|
|
|
|
class DLL_API externalUse |
|
|
|
|
|
{ |
|
|
|
|
|
public: |
|
|
|
|
|
externalUse(); |
|
|
|
|
|
~externalUse(); |
|
|
|
|
|
int add(int a, int b); |
|
|
|
|
|
int subract(int a, int b); |
|
|
|
|
|
int multiply(int a, int b); |
|
|
|
|
|
int divide(int a, int b); |
|
|
|
|
|
}; |
|
|
|
|
|
~~~ |
|
|
|
|
|
|
|
|
|
|
|
~~~ cpp |
|
|
|
|
|
#pragma once |
|
|
|
|
|
|
|
|
|
|
|
#include "pch.h" |
|
|
|
|
|
#include "externalUse.h" |
|
|
|
|
|
|
|
|
|
|
|
externalUse::externalUse(){ |
|
|
|
|
|
} |
|
|
|
|
|
externalUse::~externalUse() { |
|
|
|
|
|
} |
|
|
|
|
|
int externalUse::add(int a, int b){ |
|
|
|
|
|
return a + b; |
|
|
|
|
|
} |
|
|
|
|
|
int externalUse::subract(int a, int b){ |
|
|
|
|
|
return a - b; |
|
|
|
|
|
} |
|
|
|
|
|
int externalUse::multiply(int a, int b){ |
|
|
|
|
|
return a * b; |
|
|
|
|
|
} |
|
|
|
|
|
int externalUse::divide(int a, int b){ |
|
|
|
|
|
return a / b; |
|
|
|
|
|
} |
|
|
|
|
|
~~~ |
|
|
|
|
|
|
|
|
|
|
|
3. 创建类,导出类成员 |
|
|
|
|
|
|
|
|
|
|
|
4. 配置导出路径(项目--属性--路径) |
|
|
|
|
|
|
|
|
|
|
|
5. 点击项目--生成解决方案 |
|
|
|
|
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
|
|
|
|
6. 生成动态库得到如下文件 |
|
|
|
|
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 2.3调用 |
|
|
|
|
|
|
|
|
|
|
|
#### 2.3.1 使用DLL链接导入 |
|
|
|
|
|
|
|
|
|
|
|
* 隐式链接 |
|
|
|
|
|
|
|
|
|
|
|
~~~ |
|
|
|
|
|
#include包含声明导出函数头文件 |
|
|
|
|
|
项目设置(Linker - Input - Additional Dependencies)中添加 .lib(导入库)。 |
|
|
|
|
|
便于使用 |
|
|
|
|
|
~~~ |
|
|
|
|
|
|
|
|
|
|
|
* 显性链接 |
|
|
|
|
|
|
|
|
|
|
|
按需加载 |
|
|
|
|
|
|
|
|
|
|
|
> 静态库(.lib)与动态库(.dll/.so)区别: |
|
|
|
|
|
> |
|
|
|
|
|
> - **静态库**:编译/链接时,库代码被**直接复制并合并**到最终 EXE 文件中。 |
|
|
|
|
|
> - **动态库**:编译/链接时只记录**引用信息**(函数名、位置);代码在**运行时**由操作系统加载器动态加载。 |
|
|
|
|
|
> |
|
|
|
|
|
> **导入库(.lib - 用于隐式链接):** 一个**小的辅助库**,包含:1)告诉链接器该 DLL 存在哪些导出符号;2)包含少量跳转到 DLL 实际函数的存根代码。**不包含 DLL 的实际功能代码。** |
|
|
|
|
|
> |
|
|
|
|
|
> **头文件(.h):** 包含函数声明、类定义、宏、常量等,告诉调用者如何使用 DLL 的接口。 |
|
|
|
|
|
|
|
|
|
|
|
#### 2.3.2 加载lib调用 |
|
|
|
|
|
|
|
|
|
|
|
同静态库一样 |
|
|
|
|
|
|
|
|
|
|
|
#### 2.3.3 加载dll调用 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. **头文件引用**:包含`.h`(复制到调用方项目)可将.h放到lib中 |
|
|
|
|
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
|
|
|
|
2. 库文件配置 |
|
|
|
|
|
|
|
|
|
|
|
- 链接`.lib`(项目属性 → 链接器 → 输入 → 附加依赖项) |
|
|
|
|
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
|
|
|
|
* 添加库目录(链接器 → 常规 → 附加库目录) |
|
|
|
|
|
|
|
|
|
|
|
 |
|
|
|
|
|
|
|
|
|
|
|
| 项目 | 功能 | |
|
|
|
|
|
| ---------- | --------------------- | |
|
|
|
|
|
| C/C++ | 附加目录配置.c .h路径 | |
|
|
|
|
|
| 链接器输入 | 添加.dll所在路径 | |
|
|
|
|
|
| 链接器常规 | 附加路径添加.lib | |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[动态库添加](https://learn.microsoft.com/zh-cn/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=msvc-170) |
|
|
|
|
|
|
|
|
|
|
|
[动态库生成](https://cloud.tencent.com/developer/article/2532337) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|