(一)相关函数
在使用动态库的过程中,a.out回车加载器调用动态连接器,属于一个自动的加载,程序中可以由程序员向系统发起申请,将库加载到内存,这种叫动态加载。
dlopen(3) dlclose(3) dlerror(3) dlsym(3) …
注意:使用这些函数,在编译的时候,要加上选项 -ldl,即链接库名为dl的库
-
void *dlopen(const char* filename, int flags)
filename: 指定加载共享库的文件名,为空返回main
flags :
RTLD_LAZY : 只有在动态库里的符号被引用的时候才
RTLD_NOW:立即引用
返回值:错误返回NULL 成功返回非NULL。可以使用dlerror()诊断函数的错误的原因 -
int dlclose(void *handle);
功能:关闭共享库(引用计数减1,减到0就从内存unload)
handle: 指定要关闭的共享库
返回:成功0 失败非0 -
char *dlerror(void);
功能:获取动态链接器提供的API函数中的错误的诊断信息
返回值:错误信息字符串 -
void *dlvsym(void *handle, char *symbol, char *version);
功能:从共享库里找到符号的地址,并返回
handle:指定共享库
symbol :指定符号的名字
返回值:成功返回symbol加载到内存的地址,错误返回NULL,可以使用dlerror探测
(二)代码实操
#include <stdio.h>
#include <dlfcn.h>
typedef int (*f_t)(int, int);
//通过命令行的第一个参数传递共享库的文件名
int main(int argc, char *argv[]){
//打开一个共享库
void *h = dlopen(argv[1], RTLD_NOW);
if(h == NULL){
//printf("dlopen error...\n");
printf("%s\n", dlerror());
return -1;
}
//使用共享库中的函数
printf("dlopen success...\n");
//在动态库中找函数
f_t f = (f_t)dlsym(h, "add");
if(f==NULL){
printf("dlsym:%s\n", dlerror());
return -1;
}
//到这里f中存放的是add的地址
printf("3+4=%d\n", f(3, 4));
//关闭一个共享库
dlclose(h);
return 0;
}
在运行这个文件之前,保证要有一个动态库,详情可见C语言学习之函数库的制作和使用