Linux dlopen系列函数

发布时间 2023-06-08 23:23:02作者: 寒魔影

Linux提供了一套API来动态装载库,编译时候要加入 -ldl (指定dl库) 

dlopen()函数

函数定义

#include <dlfcn.h>
void *dlopen(const char *filename, int flag);

描述

dlopen() 用于加载以 \0 结尾的字符串文件名命名的动态共享对象(或叫动态链接库),返回一个不透明的句柄,
此句柄与 dlopen API 中的其他函数一起使用,例如 dlopen(), dlsym(), dlclose(), dlerror()。
如果 filename 为 NULL,则返回的句柄是用于主程序的。如果文件名包含斜杠,则将其解释为相对或绝对路径名。
否则动态链接器按顺序在指定目录的搜索动态链接库。
如果 filename 指定的链接库依赖于其他动态链接库,那么动态链接器也会使用相同的规则自动加载这些链接库。
(如果这些链接库又具有依赖关系则此过程可能会递归发生,依此类推)

flag 必须包含以下两个值之一
RTLD_LAZY
执行延迟绑定。仅在执行引用它们的代码时才解析符号。如果该符号从未被引用,则它永远不会被解析。(延迟绑定仅对函数引用执行;当加载动态链接库时,对变量的引用总是立即绑定)


RTLD_NOW
如果指定了此值,或者环境变量 LD_BIND_NOW 设置为非空字符串,则在 dlopen() 返回之前解析动态链接库中的所有未定义符号,如果这不能完成,则返回错误。


flag 也可以输入以下0个或多个值

RTLD_GLOBAL
此动态链接库定义的符号将可用于随后加载的动态链接库的符号解析。
RTLD_LOCAL
这与 RTLD_GLOBAL 相反,如果没有指定标志,则为默认值。 此动态链接库中定义的符号不可用于解析随后加载的动态链接库中的引用。
RTLD_NODELETE (since glibc 2.2)
不要在 dlclose() 期间卸载动态链接库。因此如果稍后使用 dlopen() 重新加载链接库,则不会重新初始化对象的静态和全局变量。
RTLD_NOLOAD (since glibc 2.2)
不要加载动态链接库。这可用于测试对象是否已经被加载到内存(如果不是则 dlopen() 返回 NULL,如果是,则返回链接库的句柄)。此标志还可用于提升已加载的动态链接库上的标志。例如如果以前使用的是 RTLD_LOCAL 标志加载的,则可以用 RTLD_NOLOAD | RTLD_GLOBAL 重新加载一次。
RTLD_DEEPBIND (since glibc 2.3.4)
将此动态库中符号的查找范围置于全局范围之前。这意味着自包含库(self-contained)将优先使用自己的符号,而不是已加载库中包含的同名全局符号。

返回值

成功时,dlopen() 返回一个非 NULL 句柄。出现错误(文件找不到、不可读、格式错误或在加载过程中导致错误)时,返回 NULL。

dlsym()函数

函数定义

#include <dlfcn.h>
void *dlsym(void *handle, const char *symbol);

描述

函数 dlsym(),以 dlopen(3) 返回的动态加载的链接库句柄以及符号名为参数,返回该符号加载到内存中的地址。如果在指定的链接库或在加载该链接库时由 dlopen(3) 自动加载的任何其他链接库中都找不到此符号,则 dlsym() 将返回 NULL。
name为符号名称,可以是函数名称或者全局变量名称

返回值

void* 指向函数的地址,供调用使用。

dlclose()函数

函数定义

#include <dlfcn.h>
int dlclose(void *handle);

描述

dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

返回值

成功返回0,失败返回非0