动态库的特性
位置无关代码(PIC - position independent code)
库中的符号,不需要提前存储在可执行文件中,只有当链接时,可执行文件才会将需要的代码函数链接到内存中。
制作动态库
编写主函数
test.c
#include<stdio.h>
int main(void){
printf("%d\n",add(3,5));
return 0;
}
编写库函数
add.c
int add(int a,int b){
return a+b;
}
sub.c
int sub(int a,int b){
return a-b;
}
生成位置无关代码
生成动态库
生成可执行文件
nm查看a.out
U代表undefined symbol
而add ,sub都没有被定义,也就是没有被分配空间
执行.a.out
报这个错误的原因在于a.out文件找不到动态库,而要想解决这个问题,可以为动态库设置环境变量
ldd a.out查看文件加载的动态库
发现我创建的libtest.so动态库显示not found
设置动态库的环境变量
注意此处的环境变量是包含动态库文件的目录
ldd a.out再次查看文件加载的动态库
再次执行.a.out
动态装载
根据载入程序何时确定动态库代码的逻辑地址,可以把动态装载分为两类:
1 静态绑定(static binding)
使用静态绑定的程序在一开始载入内存的时候,载入程序就会把程序所有调用到的
动态代码的地址算出、确定下来。这种方式使程序刚运行时的初始化时间较长,不过一
但完成动态装载,程序的运行速度就很快。
2 动态绑定(dynamic binding)
使用这种方式的程序并不在一开始就完成动态链接,而是直到真正调用动态库代码
时,载入程序才计算(被调用的那部分)动态代码的逻辑地址,然后等到某个时候,程
序又需要调用另外某块动态代码时,载入程序才又去计算这部分代码的逻辑地址。所以,
这种方式使程序初始化时间较短,但运行期间的性能比不上静态绑定的程序。
总结
前面提到的动态库特性,现在通过这个制作库的实例就可以很清楚的看到,当可执行文件只有在加载到内存中运行的那一刻,才回去找到需要的库函数,而不是提前就将库函数加载到可执行文件中,这降低了可执行文件所占用的磁盘空间。