首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将dlsym返回的指针正确赋值给函数指针类型的变量?

如何将dlsym返回的指针正确赋值给函数指针类型的变量?
EN

Stack Overflow用户
提问于 2016-04-03 18:18:08
回答 5查看 8.6K关注 0票数 24

我正在尝试在我的代码中使用dlopen()dlsym(),并用gcc编译它。

这是第一个文件。

代码语言:javascript
复制
/* main.c */

#include <dlfcn.h>

int main()
{
    void *handle = dlopen("./foo.so", RTLD_NOW);

    if (handle) {
        void (*func)() = dlsym(handle, "func");
        func();
    }

    return 0;
}

这是第二个文件。

代码语言:javascript
复制
/* foo.c */

#include <stdio.h>

void func()
{
    printf("hello, world\n");
}

下面是我编译和运行代码的方式。

代码语言:javascript
复制
$ gcc -std=c99 -pedantic -Wall -Wextra -shared -fPIC -o foo.so foo.c
$ gcc -std=c99 -pedantic -Wall -Wextra -ldl -o main main.c
main.c: In function ‘main’:
main.c:10:26: warning: ISO C forbids initialization between function pointer and ‘void *’ [-Wpedantic]
         void (*func)() = dlsym(handle, "func");
                          ^
$ ./main
hello, world

我怎样才能摆脱警告?

类型转换无济于事。如果我尝试将dlsym()的返回值类型转换为函数指针,则会收到以下警告。

代码语言:javascript
复制
main.c:10:26: warning: ISO C forbids conversion of object pointer to function pointer type [-Wpedantic]
         void (*func)() = (void (*)()) dlsym(handle, "func");
                          ^

是什么让编译器相信这段代码是正确的呢?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-04-03 20:58:43

如果你想要学院派的正确,不要尝试解析一个函数的地址。相反,从动态库中导出某种类型的结构:

在图书室里

代码语言:javascript
复制
struct export_vtable {
   void (*helloworld)(void);
};
struct export_vtable exports = { func };

在调用方中

代码语言:javascript
复制
struct export_vtable {
   void (*helloworld)(void);
};

int main() {
   struct export_vtable* imports;
   void *handle = dlopen("./foo.so", RTLD_NOW);

   if (handle) {
        imports = dlsym(handle, "exports");
        if (imports) imports->helloworld();
    }

    return 0;
}

这种技术实际上很常见,不是为了可移植性-- POSIX保证函数指针可以与void*相互转换--而是因为它允许更大的灵活性。

票数 19
EN

Stack Overflow用户

发布于 2018-12-10 23:22:05

这使得我的代码足够学究:

代码语言:javascript
复制
*(void**)(&func_ptr) = dlsym(handle, "function_name");

(我在这里找到的,http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html)

票数 10
EN

Stack Overflow用户

发布于 2016-04-03 18:55:11

若要保留代码的-pedantic选项,同时具有不严格符合的部分代码,请使用自定义警告选项将该代码分隔到单独的文件中。

因此,创建一个包装dlsym函数并返回函数指针的函数。将其放在一个单独的文件中,然后在不使用-pedantic的情况下编译该文件。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36384195

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档