前言
Linux下动态库文件的命名规范是以lib
开头,紧接着是动态库名,以.so
为后缀名,即lib + 动态库名+.so
。
动态库查找过程
在Linux下,动态库的搜索的优先级顺序为:
- 编译目标代码时指定的动态库搜索路径,保存在
.dynamic
段中,由DT_NEED类型的项表示; - 环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
- 配置文件/etc/ld.so.conf中指定的动态库搜索路径;
- 默认的动态库搜索路径
/lib
和/usr/lib
。
使用ldconfig机制
ldconfig是一个动态链接库管理命令,其目的为了让动态链接库为系统所共享。ldconfig默认的主要功能是在/lilb
、/usr/lib
以及配置文件/etc/ld.so.conf内所指定的路径下,搜索可用的动态链接库文件(库文件的格式为:lib***.so.**),并创建缓存文件供动态链接程序(ld.so)使用。缓存文件默认为/etc/ld.so.cache,该文件保存已排好序的动态链接库名字列表。 ldconfig通常在系统启动时运行,而当用户安装了一个新的动态链接库时,就需要手工运行这个命令。
环境变量
LD_LIBRARY_PATH
程序运行时,可以使用LD_LIBRARY_PATH环境变量临时指定程序所需引用的动态库的所在路径。
shell # LD_LIBRARY_PATH=/root/Workspace/CCode/test_dynamic_link ./main
Result: 15.
LD_PRELOAD
LD_PRELOAD可以指定程序预先需要装载的一些动态库。在LD_PRELOAD中配置的动态库会优先于正常规则指定搜索的动态库进行加载,并且无论程序是否依赖这些库,都会进行装载。由于全局符号介入机制的存在,LD_PRELOAD里面指定的动态库的全局符号会覆盖后面加载的同名全局符号,基于这点,我们可以很容易替换标准C库提供的函数接口,从而自定义库函数实现。
LD_DEBUG
LD_DEBUG用于打开动态链接器的调试功能,在设置这个变量时,动态链接器会在运行时打印出指定的信息。LD_DEBUG支持设置的值如下所示:
- files:打印整个装载过程中,程序依赖的动态库、装载步骤以及装载地址等信息;
- bindings:显示动态链接的符号绑定过程;
- libs:显示动态库的查找过程;
- versions:显示符号的版本依赖关系;
- reloc:显示重定位过程;
- symbols:显示符号表查找过程;
- statistics:显示动态链接过程中的各种统计信息;
- all:显示以上所有信息;
- help:显示上面的各种可选值的帮助信息。
动态库的创建与使用
为了对动态库有个更直观的认识,这里使用下面的代码说明在Linux平台下如何创建和使用动态库库:
使用gcc将addvec.c
和mulvec.c
编译成一个动态共享库文件,操作如下:
其中:
-shared
选项:指定链接器创建一个动态共享库文件;-fPIC
选项:指定编译器生成位置无关的代码。
链接动态库
为了使用生成的动态库,我们在代码里调用libvector.so
提供的外部接口:
#include <stdio.h>
#include "vector.h"
int x[2] = {1, 2};
int y[2] = {3, 4};
int z[2];
int main()
{
addvec(x, y, z, 2);
printf("z = [%d %d]\n", z[0], z[1]);
return 0;
}
可以使用gcc编译main.c
并指定链接libvector.so
文件:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PLl24DsQ-1671463270048)(media/15572453242275/%E6%88%AA%E5%B1%8F2020-08-01%20%E4%B8%8A%E5%8D%8810.31.07.png)]
其中:
-L
选项:指定动态库的路径;-l
选项:指定需要链接的动态库名。
相关参考
- 《程序员的自我修养—链接、装载与库》
- 《Linux二进制分析》