我正在尝试在我的代码中使用dlopen()
和dlsym()
,并用gcc
编译它。
这是第一个文件。
/* main.c */
#include <dlfcn.h>
int main()
{
void *handle = dlopen("./foo.so", RTLD_NOW);
if (handle) {
void (*func)() = dlsym(handle, "func");
func();
}
return 0;
}
这是第二个文件。
/* foo.c */
#include <stdio.h>
void func()
{
printf("hello, world\n");
}
下面是我编译和运行代码的方式。
$ 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()
的返回值类型转换为函数指针,则会收到以下警告。
main.c:10:26: warning: ISO C forbids conversion of object pointer to function pointer type [-Wpedantic]
void (*func)() = (void (*)()) dlsym(handle, "func");
^
是什么让编译器相信这段代码是正确的呢?
发布于 2016-04-03 20:58:43
如果你想要学院派的正确,不要尝试解析一个函数的地址。相反,从动态库中导出某种类型的结构:
在图书室里
struct export_vtable {
void (*helloworld)(void);
};
struct export_vtable exports = { func };
在调用方中
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*相互转换--而是因为它允许更大的灵活性。
发布于 2018-12-10 23:22:05
这使得我的代码足够学究:
*(void**)(&func_ptr) = dlsym(handle, "function_name");
(我在这里找到的,http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html)
发布于 2016-04-03 18:55:11
若要保留代码的-pedantic
选项,同时具有不严格符合的部分代码,请使用自定义警告选项将该代码分隔到单独的文件中。
因此,创建一个包装dlsym
函数并返回函数指针的函数。将其放在一个单独的文件中,然后在不使用-pedantic
的情况下编译该文件。
https://stackoverflow.com/questions/36384195
复制相似问题