目录
参考
概述
函数说明
示例
1. 参考
2. 概述
dlopen()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。
使用dlsym()通过动态链接库操作句柄与符号,返回符号对应的地址。
使用dlclose()来卸载打开的库。
动态库编译
编译选项:
-fPIC :PIC(Position Independent Code)表明使用地址无关代码,详细说明见[3]。
dlopen使用
头文件:#include
编译选项:编译时候要加入-ldl (指定dl库)
3. 函数说明
#include
void *dlopen(const char *filename, int flag);
char *dlerror(void);
void *dlsym(void *handle, const char *symbol);
int dlclose(void *handle);
dlopen以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。dlopen打开模式如下:
RTLD_LAZY:执行延迟绑定。只在执行引用符号的代码时解析符号。如果符号从未被引用,那么它将永远不会被解析。(延迟绑定只对函数引用执行;对变量的引用总是在加载库时立即绑定。)
RTLD_NOW:如果指定了这个值,或者将环境变量LD_BIND_NOW设置为非空字符串,则在dlopen()返回之前解析库中所有未定义的符号。如果不能这样做,将返回一个错误。
dlerror返回出现的错误。
dlsym通过句柄和连接符名称获取函数名或者变量名
dlclose卸载打开的库。
4. 示例
count.h
#ifndef _COUNT_H
#define _COUNT_H
int count;
int get();
void inc();
#endif
count.c
#include "count.h"
int get() {
return count;
}
void inc() {
count++;
}
编译动态库:$ gcc -fPIC -shared -o count.so count.c
dlopen/dlsym/dlclose使用示例:
//main.c
#include
#include
#include
#define NUM 6
#define LIBPATH ""
typedef void (*inc_func)();
typedef int (*get_func)();
const static char *exe_name = NULL;
void usage() {
printf("Usage: %s \n", exe_name);
exit(1);
}
int main(int argc, char **argv) {
exe_name = argv[0];
if (argc < 2)
usage();
const char *libpath = argv[1];
printf("libpath=%s\n", libpath);
void *handler = dlopen(libpath, RTLD_LAZY);
if (handler == NULL) {
printf("ERROR:%s:dlopen\n", dlerror());
return -1;
}
inc_func inc = (inc_func) dlsym(handler, "inc");
if (inc == NULL) {
printf("ERROR:%s:dlsym\n", dlerror());
return -1;
}
get_func get = (get_func) dlsym(handler, "get");
if (get == NULL) {
printf("ERROR:%s:dlsym\n", dlerror());
return -1;
}
for (int i = 0; i < NUM; i++)
inc();
printf("get() return %d\n", get());
dlclose(handler);
return 0;
}
编译:$ gcc -o main main.c -ldl
运行:$ ./main ./count.so
结果:
libpath=./count.so
get() return 6