# 库相关知识点 ## 静态库 ### 1.1基本概念 > 后缀(.lib .a),是一个包含编译好的目标文件(.obj/.o 文件)的归档文件包。 > > **编译时链接**: 关键特征在于它是在程序编译和链接阶段被处理的 > > 程序(.exe/另一个库)链接静态库时,----->扫描静态库找`.obj/.o` 文件----->提取合并到最终程序或目标库 * 直接包含头文件,链接文件 * 不需要复杂的加载或依赖 ### 1.2静态库生成 1. 新建项目--选择静态库--创建项目 ![](pictures\图片5.png) 2. 创建.c和.h文件 3. 点击生成解决方案 4. 生成文件 ![](pictures\图片6.png) ### 1.3静态库的调用 1. 新建项目---选择控制台应用---配置创建 2. 引用.h文件--所有配置--所有平台--配置c/c++常规----附加包含添加目录 ![](pictures\图片9.png) 3. 在链接器----常规----附加库目录----添加`.lib`文件路径 4. 就可以使用引入的库了 ![](pictures\图片10.png) #### 链接使用静态库(都可以在附加目录中添加路径) 1. 需要将.lib链接到主程序 `#pragma comment(lib,"lib/StaticLib1.lib")` 2. 添加.h文件 ~~~ cpp #pragma comment(lib,"lib/StaticLib1.lib") #include "externalUse.h" //必须包含头文件 ~~~ * 使用试例 ![](pictures\图片17.png) **项目依赖**作用是确保在构建主项目时先构建依赖项目(控制编译顺序), **项目引用**主项目不仅知道依赖,还会自动链接 `.lib` 文件(控制链接阶段) ~~~ cpp #include "pch.h" #include "use_static_lib.h" int Add(int a, int b) { return a + b; } int Tools::Get_Tools_Sum() { return Sum; } int Tools::sub(int a, int b) { return a - b; } int main() { cout << "Sdsd" << endl; Tools tool; } ~~~ ~~~ cpp #pragma once #include using namespace std; int Add(int, int); class Tools { public: int sub(int, int); int Get_Tools_Sum(); private: int Sum; }; ~~~ ## 动态库 ### 2.1 概念 > DLL 是一种**共享库机制**(Dynamic Link Library),本质上是包含**可执行代码和数据**的二进制文件(`.dll` 后缀)。不同于程序主文件(EXE),它本身不能独立运行(`DllMain` 是初始化的入口点),必须由 EXE 或 其他 DLL 在**运行时动态加载和调用**。 * 作用代码复用减少冗余 * 模块开发,节省内存,资源封装共享,拓展内容 ### 2.2 生成 1. 新建项目-->选择动态链接库——>项目配置创建 ![](pictures\图片4.png) 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. 点击项目--生成解决方案 ![](pictures\图片2.png) 6. 生成动态库得到如下文件 ![](pictures\图片3.png) #### 使用模块使用 1. 创建项目,添加.c .h文件 2. 在源中添加模块.def文件 1. ~~~~ EXPORT add ~~~~ 3. 修改输出文件为.dll ### 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. .dll放在项目可执行文件.exe相同路径 2. 创建控制台项目 3. **头文件引用**:包含`.h`(复制到调用方项目)可将.h放到lib中 ![](pictures\图片11.png) 4. 库文件配置 - 链接`.lib`(项目属性 → 链接器 → 输入 → 附加依赖项) ![](pictures\图片12.png) * 添加库目录(链接器 → 常规 → 附加库目录) ![](pictures\图片13.png) | 项目 | 功能 | | ---------- | --------------------- | | C/C++ | 附加目录配置.c .h路径 | | 链接器输入 | 添加.dll所在路径 | | 链接器常规 | 附加路径添加.lib | > 将.dll文件放到程序**.exe文件相同路径**下 [动态库添加](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)