linux下库的简介
两种库
- 静态库
-
动态库
区别:在于代码被载入的时刻不同。静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小
库的存储位置和命名规范
存储:一般放在/usr/lib和/lib下
命名规范:
1. 静态库的名字一般为libxxxx.a,其中xxxx是该lib的名称
2. 动态库的名字一般为libxxxx.so.major.minor,xxxx是该动态库的名称,major是主版本号, minor是副版本号
查看一个可执行程序依赖哪些库
ldd命令可以查看一个可执行程序依赖的共享库
在新安装一个库之后如何让系统能够找到他
如果安装在/lib或者/usr/lib下,那么ld默认能够找到,无需其他操作。
如果安装在其他目录,需要将其添加到/etc/ld.so.cache文件中,步骤如下
1. 编辑/etc/ld.so.conf文件,加入库文件所在目录的路径
2. 运行ldconfig,该命令会重建/etc/ld.so.cache文件
编写动态链接库
头文件so.h
- 1
- 2
- 3
- 4
- 5
- 6
- 7
实现文件so.c
- 1
- 2
- 3
- 4
- 5
- 6
编译动态链接库
gcc -fPIC -c so.c
//生成so.o
gcc -shared -o libtest.so so.o
(上面两行可以整合成一行:gcc so.c -fPIC -shared -o libtest.so
)
注:
- -fpic 使输出的对象模块是按照可重定位地址方式生成的(即与位置无关)。
-
-shared指定把对应的源文件生成对应的动态链接库文件libtest.so文件
通过nm -g libtest.so可以看到,导出符号表中已经有add这个符号了:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
使用动态库
-
隐式链接(编译时链接)
编写主程序main.c:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
使用gcc main.c -L. -ltest -o test
进行编译。
- -L:添加库文件的搜索路径
- -l:指定需要链接的库。该名称是处在头lib和后缀.so中的名称,如上动态库libtest.so的l参数为-l test
此时通过readelf test -d
已经能看到生成的可执行文件test的Dynamic section里依赖libtest.so了
- 1
- 2
- 3
- 4
- 5
- 6
- 7
dynamic symbols中也有一个undefined symbol(add)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
在执行隐式链接的程序之前要注意设置LD_LIBRARY_PATH
环境变量,或者把前面生成的libtest.so复制到系统路径下,否则会找不到动态库。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
-
显式链接(运行时链接)
编写主程序dyn_main.c
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
使用gcc dyn_main.c -ldl -o dyn_test
编译。
这时通过readelf dyn_test -d
可以发现,dyn_test不依赖libtest.so:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
dyn_test的dynamic symbols中也没有add:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
运行程序也不需要设置LD_LIBRARY_PATH
环境变量
- 1
- 2
0则评论给“Linux下编译动态链接库与使用详解”