1、动态库
1.1 创建动态库
创建库文件的头文件mylib.h,内容为:
int myfun(int a);
创建库文件的源文件mylib.c,内容为:
#include <stdio.h>
#include "mylib.h"
int myfun(int a)
{
return a;
}
使用如下命令生成我们的共享库libmy.so:
gcc -fPIC -shared mylib.c -o libmy.so
1.2 使用动态库
创建main.c,内容为:
#include "mylib.h"
int main()
{
int result = myfun(88);
printf("result is : %d\n", result);
return 0;
}
可见我们里面用到了我们的动态库里的函数,也包含了动态库的头文件。我们用如下命令编译:
gcc -I./ main.c ./libmy.so -o main
生成的可执行文件为main。我们执行它:
$ ./main
./main: error while loading shared libraries: libmy.so: cannot open shared object file: No such file or directory
这说明编译的时候可以找到这个库,但是执行的时候找不到它。解决办法有如下几个:
1)export LD_LIBRARY_PATH=自定义动态库的路径
(只能起到临时作用,关闭终端后失效)
LD_LIBRARY_PATH : 指定查找共享库(动态链接库)时除了默认路径之外的其他路径,该路径在默认路径之前查找
2)将上述命令写入home目录下的.bashrc文件中,保存后重启终端生效(永久)
3)直接将动态库拷贝到user/lib的系统目录下(强烈不推荐!!)
4)将libmy.so所在绝对路径追加入到/etc/ld.so.conf文件,使用sudo ldconfig -v 更新
我们使用的方法是第1)种:
export LD_LIBRARY_PATH=/home/wjbvb2/study/gcc/gcc
$ ./main
result is : 88
2、静态库
2.1 创建静态库
创建库文件的头文件:
#include <stdio.h>
int my_static_lib_func(int a, int b);
创建库文件的源文件:
#include "mystaticlib.h"
int my_static_lib_func(int a, int b)
{
return a+b;
}
编译静态库:
$gcc -c mystaticlib.c -o mystaticlib.o #先将mystaticlib.c编译成.o文件
$ar rcs libmystaticlib.a mystaticlib.c #将mystaticlib.o生成静态库mystaticlib.a
$ ls
libmystaticlib.a main.c mystaticlib.c mystaticlib.h mystaticlib.o
rcs:
r将文件插入静态库中
c创建静态库,不管库是否存在
s写入一个目标文件索引到库中,或者更新一个存在的目标文件索引
2.2 使用静态库
写main.c:
#include "mystaticlib.h"
int main()
{
int result = my_static_lib_func(30, 80);
printf("result is %d \n", result);
return 0;
}
编译方法有两种:
$ gcc main.c -L./ -lmystaticlib -I./ -o main
或者
$ gcc main.c ./libmystaticlib.a -o main2
$ ./main
result is 110
$ ./main2
result is 110
3、同时有静态库,又有动态库,如何区分
我们把刚才代码继续创建一份动态库 libmystaticlib.so(虽然看着很奇怪啊,名字叫静态库,结果又是so文件):
$ gcc mystaticlib.c -fPIC -shared -o libmystaticlib.so
$ ls
libmystaticlib.a libmystaticlib.so main main2 main.c mystaticlib.c mystaticlib.h mystaticlib.o
这时候,这个目录下有个libmystaticlib.a,又有个libmystaticlib.so,那么我们用如下命令编译main.c的时候,会用到哪个库呢?
$gcc main.c -L./ -lmystaticlib -I./ -o main3
$ ./main3
./main3: error while loading shared libraries: libmystaticlib.so: cannot open shared object file: No such file or directory
可见如果有了libmystaticlib.so存在,那么编译的时候链接的是libmystaticlib.so,而不是libmystaticlib.a。运行的时候它找的是libmystaticlib.so。
那么如果两个库都存在,又想静态链接怎么办呢?用-static:
$ gcc main.c -L./ -lmystaticlib -I./ -static -o main4
$ ./main4
result is 110
我觉得可以将我们生成的4个可执行文件做个总结:
可执行程序 | 生成时的命令,以及当时有的库 | readelf -d结果(只列出依赖的动态库) |
main | gcc main.c -L./ -lmystaticlib -I./ -o main 当时只有libmystaticlib.a,没有so文件 | Shared library: [libc.so.6] |
main2 | gcc main.c ./libmystaticlib.a -o main2 当时只有libmystaticlib.a,没有so文件 | Shared library: [libc.so.6] |
main3 | gcc main.c -L./ -lmystaticlib -I./ -o main3 当时libmystaticlib.a和libmystaticlib.so都存在 | Shared library: [libmystaticlib.so] Shared library: [libc.so.6] |
main4 | gcc main.c -L./ -lmystaticlib -I./ -static -o main4 当时libmystaticlib.a和libmystaticlib.so都存在 | There is no dynamic section in this file. |
由此看,加了-static关键字后,连c库都被静态链接进去了。