静态库是编译期绑定的代码复用方案,适合:
优点
独立性:可执行文件包含所有依赖,无需外部库文件,部署简单。
性能:函数调用无额外开销(无动态链接加载过程)。
兼容性:避免版本冲突(如“DLL Hell”问题)。
代码优化:编译器可进行全程序优化(LTO)。
缺点:
体积大:相同库代码被多次复制到不同程序,占用磁盘/内存。
更新困难:库更新需重新编译所有依赖它的程序。
内存浪费:多个进程无法共享同一库的物理内存。
第一,创建新项目,选择静态库。
第二,添加.c文件,同时编写.h和.c文件进行编写,编写完成后进行编译,生成.lib格式的静态库文件。
静态库调用有三种方式:
第一,在工程中调用静态库需要静态库路径,首先include,“内填写路径,并最后写.h文件名”,其次需要
#pragma comment进行静态库声明,然后就可以在函数内使用静态库。
第二,在项目属性 -- > 链接器 --> 常规 --> 附加库中添加静态库.lib文件的地址,并在输入页面附加依赖项中添加.lib文件。
第三,直接将lib文件添加到项目中。
以上三种方法都需要添加.h文件到项目。
程序内可以使用相对路径也可以使用绝对路径,相对路径时需要将静态库文件复制到工程文件内。
参考上一项。
动态库(Dynamic Link Library, DLL / Shared Object, SO)是一种在程序运行时才被加载的代码库,允许多个程序共享同一份内存中的库副本
优点:
节省资源:多个进程共享同一库,减少内存/磁盘占用。
更新灵活:更新库文件后,所有程序自动使用新版本(需兼容)。
模块化:支持插件机制(运行时加载)。
热修复:可替换库文件修复问题(无需重编译程序)。
缺点:
部署复杂:需确保目标系统存在正确版本的库(依赖管理)。
版本冲突:不同程序依赖同一库的不兼容版本(如DLL Hell)。
性能损耗:首次加载需地址重定位,轻微运行时开销。
安全性:恶意替换库文件可能导致安全隐患。
通过dllimport与dllexport导出语句生成动态库,新建空白项目,添加头文件源文件进行编写,在头文件中添加导出语句即可,然后将方案属性选择动态库,生成解决方案即可导出动态库。如图所示。
下图是动态库导出的文件夹状态。
通过def文件进行生成动态库。生成前需要添加def文件,然后添加代码进行生成操作。
动态库的调用分为隐性和显性调用两种。
第一,隐性调用,需要将动态库生成的.lib、.h和.dll文件添加到项目文件下,其次在项目工程中,通过属性-->链接器-->输入-->添加依赖项.lib文件,同时工程内添加.h头文件,然后可以进行调用了。
第二,显性调用
定义函数指针,并声明函数指针变量,然后通过程序动态加载dll文件到内存中(HINSTANCE hModule = LoadLibrary(“TestDll.dll”);),并获取指针地址,最后调用函数。
#pragma comment (lib,地址),地址可以选择绝对地址或者相对地址。
HINSTANCE hDll = LoadLibrary(TEXT(“DLLTest.dll”));