动态链接库是一种代码共享形式,便于模块化的开发与扩展。作为开发人员有必要详细了解其过程。
动态链接库的使用过程主要涉及到两个部分:
1.动态链接器 ld.so
2.ldconfig
其中:
ld.so负责加载应用程序所需的soname对应的共享库
ldconfig负责维护soname到实际共享库的链接的高速缓冲文件
高速缓冲文件中维护的链接关系被ld.so在加载时进行使用。
动态库的创建过程如下:
先描述一下创建过程中用到的几个名字:
动态库实际名字:
形如:
libexample.so.1.2.3
其中example是用于辨识库的主要部分,用于gcc的-l选项之后:gcc -lexample。
1为major number,主版本号,不同的主版本号之间不要求兼容性。
2为minor number,次版本号,较大的次版本号需要保证向后兼容,因此一般用于追加新接口。
3为patch number,又称发行号,release number,用于bugfix。
soname:
形如:
libexample.so.1
包括主版本号,主要用于写入共享库头中以供链接器写入应用程序,并用于在ld.so加载动态库时查找高速缓冲文件。
动态库链接名字:
libexample.so
用于链接器在链接过程中查找动态库。
示例:
示例过程简要描述:
创建一个简单的共享库libcalc.so
创建一个应用程序调用libcalc.so
libcalc.so的源码如下:
calc.h头文件(包含函数声明):
int add(int,int);
int minus(int,int);
calc.c 源文件(函数的实现):
int add(int a,int b) {
return a+b;
}
int minus(int a,int b) {
return a-b;
}
应用程序源码如下:
main.c:
#include <stdio.h>
#include "calc.h"
int main() {
printf("%d %d\n",add(5,3),minus(5,3));
return 0;
}
创建共享库:
1.文件列表:
2.编译可加载到任何地址的代码,注意选项-fPIC
3.链接生成共享库,注意-shared与-Wl,-Wl负责把-soname libcalc.so.1传递给实际完成工作的链接器。
4.生成两个符号链接,libcalc.so.1用于ld.so查找动态链接库并加载,libcalc.so用于链接器编译应用程序时查找符号。
5.链接生成应用程序,注意各选项。
6.尝试执行生成的应用程序,应该是无法找到共享库的,注意这里报的名字是libcalc.so.1,是libcalc.so.1.0.0的soname,并非链接时使用的libcalc.so,也不是libcalc.so指向的库文件名。
7.用根用户权限修改一下ld.so查找时的路径配置,默认情况下在/etc/ld.so.conf,此处可以修改ld.so.conf.d目录下的内容,为了便利就直接修改该配置文件了。
8.修改后的配置文件
9.使用ldconfig更新高速缓存文件,注意由于之前写的当前文件,则需在共享库所在目录下执行ldconfig,退出根用户,执行应用程序,结果成功。
10.最后不要忘了将ld.so.conf还原。