void * dlopen( const char * pathname, int mode );
#include
mode:分为两种
RTLD_LAZY: 在dlopen返回前,对于动态库中存在的未定义的变量(如外部变量extern,也可以是函数)不执行解析,就是不解析这个变量的地址。
RTLD_NOW: 在dlopen返回前,解析出每个未定义变量的地址,如果解析不出来,在dlopen会返回NULL,错误为: undefined symbol: xxxx.......
RTLD_LOCAL
RTLD_GLOBAL 允许导出符号,即,使库中解析的定义变量在随后的其它链接库中可用;可以让后面load的动态库可以调用这个库里用extern 包的接口
RTLD_GROUP
RTLD_WORLD
filename:是相对路径时,会依次在以下地方找这个文件
1) user's LD_LIBRARY_PATH environment variable.
2) /etc/ld.so.cache.
3) /usr/lib
4) /lib.
**注意:
用dlopen多次打开同一个库返回同一个句柄,必须调用相同次数的dlclose才会真的析构。
返回值:
错误返回:NULL
成功返回:库引用
编译时候要加入 -ldl (指定dl库)
例如
gcc foo.c -rdynamic -o foo -ldl
const char *dlerror(void)
#include
说明:
会输出dlopen,dlclose,dlsym的任何出错信息,如果没有出错信息,其为NULL。
如果连续调用,第一次为出错信息,第二次为NULL。
int dlclose(void *handle);
#include
说明:
关闭句柄并且取消共享目标文件的映射
void *dlsym(void *handle, char *symbol);
#include
说明:
handle是由dlopen打开动态链接库后返回的指针,symbol就是要求获取的函数的名称,函数返回值是void*,指向函数的地址,供调用使用.
/*
* Demo: Dynamic Function Mapping Using 【dlxxx_Function_Family】
*/
#include
#include
#include
int main(int argc, char **argv)
{
void *handle;
double (*cosine)(double);
char *error;
handle = dlopen("libm.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
dlerror(); /* Clear any existing error */
/* Writing: cosine = (double (*)(double)) dlsym(handle, "cos");
would seem more natural, but the C99 standard leaves
casting from "void *" to a function pointer undefined.
*/
cosine = dlsym(handle, "cos"); // also right
// *(void **) (&cosine) = dlsym(handle, "cos"); //recommendated!
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(EXIT_FAILURE);
}
printf("%f\n", (*cosine)(2.0));
dlclose(handle);
exit(EXIT_SUCCESS);
}
阅读(3798) | 评论(0) | 转发(0) |