1.库的基本概念
库是一组预先编译好的代码和数据的集合,提供了可重用的功能,供其它程序调用。在Windows开发中,库主要分为两种类型:
1.1 静态库(lib)
静态库文件(.lib)包含的【函数和数据】被编译到一个二进制文件(.lib)。在使用静态库时,编译链接可执行文件需要链接器从库中复制这些函数和数据,并把它们和应用程序的其他模块组合起来,创建最终的可执行文件(.exe) 当发布产品时,只需要发布这个可执行文件(.exe),并不需要发布被使用的静态库文件(.lib)。
1.2 动态库(dll)
在使用动态库的时候,编译后往往提供两个文件:(import library)引入库文件(.lib)和(.dll)文件。 引入库文件(.lib)包含【DLL导出的函数和变量的符号名】,而动态库文件(.dll)文件包含【DLL实际的函数和数据】。在使用动态库时,编译链接可执行文件需要链接该DLL的引入库文件(.lib),DLL中的函数代码和数据并不可复制到可执行文件,直到可执行程序(.exe)运行时,才去加载所需的DLL,并将该DLL映射到进程的内存空间中,然后访问DLL中导出的函数。 在发布产品时,除了发布可执行文件(.exe)以外,同时还需要发布该程序将要调用的动态链接库(.dll)。
1.3 库的作用和优势
- 代码复用:避免重复造轮子
- 模块化开发:功能分离,便于维护
- 隐藏实现:提供接口,保护知识产权
静态库(Static Library)
静态库在Windows下通常以.lib为扩展名,在编译链接时将其代码直接复制到最终的可执行文件中。
静态库的创建和使用:
1.新建项目--->静态库
2.配置属性--->常规--->配置类型:静态库(.lib)
在使用项目的根目录创建include和lib文件夹,分别添加静态库中.h和.lib相关文件,
创建静态库项目后,在vs的同一个解决方案下创建使用的项目,并把它设置为启动项目。
在使用项目的属性界面打开C/C++的常规,编辑附加包含目录,在其中添加静态库中需要用到的类的头文件。在链接器的输入界面编辑添加附加依赖项,加入静态库.lib文件的路径。
注:- 关注是Debug模式还是Release模式。
- 上述使用方法可能讲的不是很清楚,待我习得CMake后重述它法。
- 也可以在代码中直接引用: #pragma comment(lib, "xxxxx.lib") #pragma comment(lib) 是一个编译器指令,它告诉链接器在链接时需要查找并链接指定的库文件。这个指令在编译阶段被处理,信息被写入到生成的目标文件(.obj)中。
动态库(Dynamic Link Library)
动态库在Windows下以.dll为扩展名,程序在运行时动态加载库文件,多个程序可以共享同一个DLL。
动态库的创建与使用:
同上静态库,区别是根目录创建include,dll,lib三个文件夹。
项目配置:
- 预处理器定义:添加MATH_DLL_EXPORTS
- 配置类型:动态库(.dll) 需要的文件:
- 头文件(.h):声明导出函数和类
- 导入库(.lib):包含DLL的导出信息
- 动态库(.dll):运行时加载的实际代码
两者使用场景对比
适合使用静态库的场景
- 小型工具程序
- 需要独立部署的应用
- 性能要求极高的场景
- 不希望有外部依赖的项目 适合使用动态库的场景
- 大型模块化系统
- 需要热更新的应用
- 多个程序共享功能的场景
- 插件系统架构
二者的不同点在于代码被载入的时刻不同。
-
静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库,因此体积较大。
-
动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在,因此代码体积较小。 动态库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。带来好处的同时,也会有问题!如经典的DLL Hell问题,关于如何规避动态库管理问题,可以自行查找相关资料。