动态库与位置无关代码

来源:互联网 发布:android语音助手源码 编辑:程序博客网 时间:2024/04/29 16:12

静态库的缺点:
1 链接后产生的可执行文件包含了所有需要调用的函数的代码,因此占用的磁盘空间较大。
2 如果有多个(调用相同库函数的) 进程在内存中同时运行,内存中就有多份相同库函数代码,故占内存空间较大。

所以产生了动态库,在程序装载入内存时才真正把库函数代码链接进来确定它们的地址。并且在上面2的情况下,内存中也只存有一份函数代码(但动态库的数据可能有多份副本,当某一连接到动态库的进程要修改库的数据时,OS就复制一份数据的副本,然后修改进程的地址空间映射,使其指向新的数据副本)。
由于以上特点,动态库的代码需要能够被加载到不同进程的不同地址,故其代码要经过特别的编译处理,这种代码即位置无关代码(Position independent code,PIC)

对于上一节静态库中的例子,要编译成PIC则:
$gcc -c -fPIC testa.c testb.c
$gcc -shared -o libtest.so testa.o testb.o
$gcc test.c -L. -lfun
这时已经可以生成可执行文件,但要是系统能使用动态库,还要设置环境变量LD_LIBRARY_PATH:
$export LD_LIBRARY_PATH=/xxx/yyy/zzz      /*/xxx/yyy/zzz是libtest.so所在目录*/

现在查看输出文件符号表:
$nm a.out |less
...
00000000 U f      /*U表示还未确定*/
...

运行a.out时,首先检查内存中是否有相同的库代码在运行,如果有,则计算出正确的逻辑地址以备使用;否则先确定逻辑地址,再载入代码到内存中。

根据载入程序何时确定动态库代码的逻辑地址,可分为:
1静态绑定(static binding)
程序一载入内存就把动态代码地址算出,这样程序刚运行时初始化时间较长,但一旦完成动态装载,程序运行就很快。
2动态绑定(dynamic binding)
在程序真正调用动态库中代码时才计算相关逻辑地址,故初始化时间较短,但运行性能不如静态绑定。

原创粉丝点击