动态共享库使用

1. 代码

root@romulus-laptop:/work/test/sharedObject# cat a.c
#include<stdio.h>

void printA(){
    printf("in method printA of a.c./n");
}
root@romulus-laptop:/work/test/sharedObject# cat main.c
int main() {
    printA();
    return 0;
}

 

2. 生成共享库

root@romulus-laptop:/work/test/sharedObject# gcc -shared -o liba.so a.c

 

3. 使用共享库进行编译

root@romulus-laptop:/work/test/sharedObject# gcc -o main main.c -la -L . // la指定共享库的名字是a,即liba.so

 

4. 设置可执行程序运行是寻找共享库的路径

将liba.so拷贝到/usr/local/lib下

a. 设置环境变量

LD_LIBRARY_PATH=/usr/local/lib

程序运行进入main入口前,环境变量是在一个map中,供程序需要共享库决定是否加载时使用。

b. 重新设置/etc/ld.so.cache

参见:http://blog.csdn.net/xiaoxiaosunzhao/archive/2011/03/10/6238667.aspx

 

5. 使用动态链接库编译,只是ld在将需要使用动态链接库的函数放到一张表中:

动态链接器可以为每个被链接的函数做相当多的工作,所以大部分链接器都是不积极的。只有在函数被调用时,它们才实际做一些工作。C 程序库中有一千多个外部可见的符号,有大约三千多个本地符号,因此这种 方法可以节省非常多的时间。

实现此奇妙功能的是一个称为 过程链接表(Procedure Linkage Table) (PLT)的数据块,它是程序中 的一个表,列出了程序所调用的每一个函数。当程序开始运行时,PLT 包含每个函数的代码,以便查询运行期链接器,从而获得已加载某个函数的地址。然后它会在表中填入这个条目并跳转到那个已加载函数。当每个函数被 调用时,它的 PLT 中的条目就会被简化为一个到那个已加载函数的直接跳转。

不过,重要的是,要注意到还有一个间接的额外层次 —— 可以通过跳转到某个表来解析每个函数调用。

比如,更新了liba.so, 然后使用新的共享库进行编译,但是运行期指定旧的共享库,那么仍然使用的是旧的共享库。

 

你可能感兴趣的:(动态共享库使用)