在使用动态链接库时,将动态链接库函数变为函数指针的一些使用小方法(dlopen,dlsym)

static void *handle;
static int (*ptr_init)(struct mr * instance, const char * mrz);

handle = dlopen("/path/to/library.so", RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE);
ptr_init = (int (*)(struct mr * instance, const char * mrz))dlsym(handle, "init");

这段代码加载了一个动态链接库文件,并从中获取了一个名为 "init" 的函数的指针。下面是对代码的解释:

1. `static void *handle;`: 声明了一个静态变量 `handle`,它将被用来存储动态链接库的句柄。

2. `static int (*ptr_init)(struct mr * instance, const char * mrz);`: 声明了一个函数指针 `ptr_init`,它可以指向一个带有特定签名的函数,该函数接受一个 `struct mr *` 类型的实例和一个 `const char *` 类型的字符串作为参数,并返回一个 `int` 类型的值。

3. `handle = dlopen("/path/to/library.so", RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE);`: 使用 `dlopen` 函数加载了一个动态链接库文件,并将其句柄存储在变量 `handle` 中。加载的文件路径是 '/path/to/.so',打开标志包括 `RTLD_NOW`、`RTLD_LOCAL` 和 `RTLD_NODELETE`,

  • RTLD_NOW: 这是 dlopen 函数的打开标志之一,它告诉 dlopen 在加载动态链接库时立即解析其中所有的符号。这意味着如果有任何未解析的符号,dlopen 将会失败并返回错误。

  • RTLD_LOCAL: 这是 dlopen 函数的另一个打开标志,它指定在动态链接库中加载的符号对动态链接库本身及其后续加载的动态链接库是私有的。这意味着在动态链接库内部的符号不会被动态链接到其他动态链接库。

  • RTLD_NODELETE: 这也是 dlopen 函数的一个打开标志,它指示在使用 dlclose 函数关闭句柄时不要从进程中卸载动态链接库。这意味着即使在使用 dlclose 关闭句柄后,动态链接库仍然保持加载状态。

4. `ptr_init = (int (*)(struct mr * instance, const char * mrz))dlsym(handle, "init");`: 使用 `dlsym` 函数获取了名为 "init" 的函数在动态链接库中的地址,并将其赋值给函数指针 `ptr_init`。在这里,我们显式地将返回值强制转换为与 `ptr_init` 的声明相匹配的函数指针类型。

通过这样的操作,我们可以在程序运行时动态地加载一个动态链接库,并获取其中的函数指针,从而可以在程序中调用该函数。

`dlsym` 和 `dlopen` 函数的返回值在成功时为非空指针,失败时为 NULL。

- `dlopen`: 如果成功加载了动态链接库,则返回一个非空的句柄,表示成功加载的动态链接库的句柄。如果加载失败,则返回 NULL,并且可以通过 `dlerror` 函数获取详细的错误信息。

- `dlsym`: 如果成功找到了指定符号,则返回指向该符号的指针,如果未找到,则返回 NULL,并且同样可以通过 `dlerror` 函数获取错误信息。

因此,在实际应用中,你可以使用类似以下的代码来检查 `dlopen` 和 `dlsym` 函数是否成功执行:

void *handle = dlopen("/path/to/library.so", RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE);
if (handle == NULL) {
    fprintf(stderr, "Failed to open library: %s\n", dlerror());
    // 处理加载失败的情况
}

int (*ptr_init)(struct mr *, const char *);
ptr_init = (int (*)(struct mr *, const char *))dlsym(handle, "init");
if (ptr_init == NULL) {
    fprintf(stderr, "Failed to find symbol 'init': %s\n", dlerror());
    // 处理未找到符号的情况
}

这样,你就可以在加载动态链接库或获取函数指针失败时得到相应的错误信息并进行处理。

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值