linux 的动态库和静态库

库从本质上来说,是一种可执行代码的二进制格式,可以载入内存中执行。库分静态库和动态库两种
静态库:这类库的名字一般是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_one
souce_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.out
souce_one
souce_two

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。