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