库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行,代码可复用。库分静态库和动态库两种,两者都在程序进行链接时加入,但链接方式不同
静态链接库
命名
- Unix:libxxx.a
- Windows:xxx.lib
静态链接
在链接阶段会将汇编生成的目标文件.o
与引用到的库一起链接打包到可执行文件中;因与目标文件一起链接为可执行文件,则可简单看成是一组目标文件.o/.obj
的集合,即很多个文件打包成一个文件
特点
- 静态库对函数库的链接是放在编译时期完成的
- 程序在运行时与函数库再无瓜葛,移植方便,因把所有使用的的函数已经被编译进去
- 浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件
静态库的使用
- 需包含一个对应的头文件告知编译器lib文件里面的具体内容
- 设置lib文件允许编译器去查找已经编译好的二进制代码
依赖性
静态链接表示依赖性,在编译链接后,lib
中所需要的资源已经存在于可执行文件中,即静态存在,没有依赖性
动态链接库
命名
- Linux:libxxx.so
- Mac OS:libxxx.dylib
- Windows:xxx.dll
动态链接
动态库在程序编译时并不会被连接到目标代码中,它本身只保留个接口,只在程序运行是才被载入;不同的应用程序如果调用相同的库,在内存里只需要有一份该共享库的实例,这就不会造成空间的浪费
特点
- 动态库把对一些库函数的链接载入推迟到程序运行的时期
- 可以实现进程之间的资源共享(因此动态库也称为共享库)
- 将一些程序升级变得简单
- 可以真正做到链接载入完全由程序员在程序代码中控制(显式调用)
动态库的使用
程序运行时需要加载动态库,对动态库有依赖性,需要手动加入动态库
依赖性
动态库具有实时性,在运行的时候载入需要的资源,那么必须在运行的时候提供需要的动态库,有依赖性,运行时候没有找到库就不能运行了
Windows下lib与dll的区别
- lib全部链接在可执行文件里面,不可分开,但dll可以分开,使用时放在可执行文件目录下
- 静态库中不能再包含其他的dll和静态lib,而dll中可以再包含
动态链接时
动态链接的情况下,一般都会有两个文件,一个是.dll
,另一个是导入库.lib
,lib包含被dll导出的函数名称和位置,没有函数实现,dll包含实际的函数和数据,应用程序使用lib文件链接到dll文件,在应用程序的可执行文件中存放的不是被调用函数的代码,而是dll中相应函数代码的地址
静态库lib与动态库生成的导入库lib的区别
静态库本身就包含了实际执行代码、符号表;而导入库的实际执行代码都在dll
中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息,并没有函数实现