基于VS的静态链接库与动态链接库

1>什么是库

库是写好的现有的,成熟的,可以复用的代码现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。

本质上来说库是一种可执行代码的二进制形式可以被操作系统载入内存执行。库有两种:静态库.lib和动态库.dll ,所谓静态、动态是指链接。下图是程序编译的过程
基于VS的静态链接库与动态链接库

动态库是LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供。
静态库是LIB包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库。(所以无论是动态链接库还是静态链接库,都会有lib文件

2>静态链接库

之所以叫静态链接库,是因为在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。静态库与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似,其实一个静态库可以简单看成是一组目标文件(.o/.obj文件)的集合。
静态链接库的特点:
程序在运行时与函数库再无瓜葛,移植方便;
浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。
静态库对程序的更新、部署和发布页会带来麻烦,如果静态库更新,使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新)。
基于VS的静态链接库与动态链接库
静态链接库的使用

  • 需要的文件: 头文件 .h 、静态库 .lib;
  • 头文件.h中有函数的声明,使用静态链接库的项目需要引用该文件才能编译通过;
  • .lib包含了实际执行代码、符号表等等;
  • 加载lib的方法: 法1:使用编译链接参数或者VS的配置属性来设置,法2:使用pragma编译语句,例如pragma comment(lib,“a.lib”);
  • .lib中的指令将全部被直接包含在最终生成的 EXE 文件中。

3>动态链接库

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例(如下图), 规避了空间浪费问题。动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只需要更新动态库即可,增量更新。
基于VS的静态链接库与动态链接库
动态链接库的使用

  • 需要的文件: 头文件 .h 、动态链接库的.lib文件,动态链接库的dll文件;
  • 头文件.h和静态链接库使用时的作用一样,使用动态链接库中的函数的项目需要引用该文件才能编译通过;
  • .lib包含了函数所在的DLL文件和文件中函数位置的信息,.dll包含了实际执行代码、符号表等等;
  • 加载lib的方法:lib是编译链接是用的,跟使用静态链接库时一样有两种方法:法1:使用编译链接参数或者VS的配置属性来设置 ;
    法2:使用pragma编译语句,例如pragma comment(lib,“a.lib”);
  • 加载dll的方法:dll是运行时用的,链接了lib之后形成的EXE可执行文件中已经有了dll的信息,所以只要把dll放在和exe同一个目录下就可以了,运行时根据EXE需要自动加载dll中的函数。

动态库把对一些库函数的链接载入推迟到程序运行的时期,可以实现进程之间的资源共享,将一些程序升级变得简单。