目录
- 1.静态库
- 2.动态库
- 3.静态库的使用区别
- 总结
1.静态库
我们在linux中已经帮我们下载好了C和C++所需要的各种库,库也是文件,实际上就是各种接口的实现,我们在使用系统提供的譬如printf等函数时,就是使用系统中的库文件。使用一个库文件不仅需要对应的头文件(函数声明),还要有对应的库文件(函数实现)。
我们学过头文件展开是在预处理阶段就进行的,链接库是在链接阶段进行的。
接下来,我们通过自定义实现一个库文件,更加深入的理解如何自己实现静态库以及使用下载的各种静态库。
我们在写代码的时候需要多个文件使用,需要函数声明的文件,以及函数实现的文件,这其实跟库一个道理。
如何在不暴露代码的情况下让别人使用我们的接口,这实际上就是打包一个静态库,模仿linux系统。
第一步,将我们的函数实现.c文件编译成.o文件(可重定位二进制文件)
第二步,将所有的.o文件打一个包
使用指令: ar -rc 包名 *.o
包的名字有特定的规范 : lib + 包名 + .a
第三步,模仿linux系统,将包放到一个Lib的文件中,头文件放到Include文件中。
和linux类似,将头文件放到一个文件夹中,开放式的。将实现打一个包放到另一个文件夹中。
第四步,使用。我们自己打的包又称为第三方库,第一方是语言,第二方是OS。系统没有识别第三方库的功能,所以我们在使用的时候不仅包含头文件,还必须指定头文件所在位置以及自定义包的名字(去掉开头lib和后缀.a)。
此时,如果别人想使用我们实现的函数接口,我们可以将Include文件和Lib文件直接打个压缩包发给别人,别人在使用是解压缩包,即可像我们这样去使用。
小技巧:我们可以将自己的头文件放到操作系统默认搜索头文件的目录中去,将自己实现的库放到系统默认搜索库的目录中去。
2.动态库
自定义实现一个动态库。
第一步,将函数实现.c文件编译成.o文件
需要加一条指令 -fPIC 位置无关码
第二步,将.o文件打一个包
动态库命名规则 lib + 文件名 + .so
由此,我们动态库已经制作好,如何去使用呢?三种使用方法
Ⅰ 配置PATH(临时,OS每次重启会将用户自己配置的环境变量重置)
系统中有一个命名为 LD_LIBRARY_PATH的环境变量用来查找动态库的位置
我们可以将动态库所在路径配置到环境变量下。
Ⅱ 将当前自定义的动态库在系统/lib64下创建一个软连接
Ⅲ 配置文件
在 /etc/ld.so.conf.d/ 路径下创建一个后缀为.conf的文件,文件内容写动态库的路径
将动态库的文件位置写入创建的文件中
使用ldconfig指令将新写入的配置文件生效
3.静态库的使用区别
静态库的使用原理
动态库的使用原理
总结
- 静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
- 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
- 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
- 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)
- 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。
- 动态库和静态库同时存在,优先使用动态链接
- 编译器,在链接的时候,如果提供的库既有动,又有静,优先动。只有静,只能静态链接。