linux 的动态库和静态库

来源:互联网 发布:网络协议的作用和功能 编辑:程序博客网 时间:2024/06/08 13:27

库从本质上来说,是一种可执行代码的二进制格式,可以载入内存中执行。库分静态库和动态库两种
静态库:这类库的名字一般是libxxx.a, xxx是库的名字。利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合到目标代码中。优点是,变异后的执行程序不需要外部的函数库支持。确定是,如果静态函数库改变了,那么程序需要重新编译。
动态库:这类库的名字一般是libxxx.M.N.so,xxx是库的名字,M是库的主版本号,N是库的副版本号。(版本号不是必须的)。动态库是在程序运行时动态申请并加载的,需要程序的运行环境中必须提供相应的库。
要使用静态的程序库时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功,静态程序库也就不再需要了。然而,对动态库而言,就不是这样。动态库会在执行程序内留下一个标记指明当程序执行时,首先必须载入这个库。由于动态库节省空间,linux下进行连接的缺省操作是首先连接动态库,也就是说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。

静态库的制作
准备两个库的源码文件 souce_one.c和souce_two.c

$ cat souce_one.c#include <stdio.h>void print1(){    printf("souce_one\n");}$ cat souce_two.c#include <stdio.h>void print2(){    printf("souce_two\n");}

编译成静态库:

$ gcc -c souce*.c$ ar -rsv libmytest.a souce*.o

准备测试程序测试生成的静态库:

$ cat test.c int main(){    print1();    print2();    return 0;}

编译链接测试程序:

gcc test.c$ gcc test.c -L./ -lmytest$ ./a.out souce_onesouce_two## -L指定库文件的路径## -l使用的库的名字

动态库的制作
这里还是使用上面的3个文件souce_one.c、souce_two.c 、test.c
编译动态库

$ gcc -c souce_*.c$ gcc -shared -fPCI -o libtest.so souce_*.o## -shared :指定生成动态链接库## -fPIC:表示编译为位置独立的代码

测试动态库

$ gcc test.c  -ltest## -l 指定连接阶段引用共享库$  ./a.out  #执行程序时会报错./a.out: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory$  ldd ./a.out ##  使用ldd查看依赖,发现libtest库没有找到    linux-gate.so.1 =>  (0xb7783000)    libtest.so => not found    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75cb000)    /lib/ld-linux.so.2 (0xb7784000)$ cp libtest.so /usr/lib/  #将动态库拷贝到程序默认查找的目录$ ./a.outsouce_onesouce_two
1 0