- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在 C
中使用 dlsym()
我有一个问题 dlsym()
的返回值是否应该显式转换或者它是否被正确地隐式转换。这是函数:
double (*(compile)(void))(double x, double y)
{
if (system("scan-build clang -fPIC -shared -g -Wall -Werror -pedantic "
"-std=c11 -O0 -lm foo.c -o foo.so") != 0) {
exit(EXIT_FAILURE);
}
void *handle;
handle = dlopen("./foo.so", RTLD_LAZY);
if (!handle) {
printf("Failed to load foo.so: %s\n", dlerror());
exit(EXIT_FAILURE);
}
foo f;
f = (foo)dlsym(handle, "foo");
if (!f) {
printf("Failed to find symbol foo in foo.so: %s\n", dlerror());
exit(EXIT_FAILURE);
}
return f;
}
compile()
函数不接受值并返回指向函数的指针,该函数将两个 double
作为输入并返回一个 double。然后我设置了一个系统调用来编译一个共享对象 foo.so
。然后,我使用 dlopen()
打开 foo.so
。然后 dlsym()
在 foo.so
中找到 foo
并返回我在 a 中定义的 foo
类型的对象标题为:
typedef double (*foo)(double, double);
我必须转换 dlsym()
吗?
最佳答案
编写 C 标准是为了假设指向不同对象类型的指针,尤其是指向与对象类型相反的函数的指针,可能具有不同的表示形式。这就是为什么一般来说,您不想混合使用指针,或者如果您这样做,现代编译器会警告您,如果您想消除警告,您通常会使用显式强制转换。
dlsym
,另一方面,由于它的存在本身就假定所有指针都几乎相同,因为它应该能够向您返回指向任何数据类型的任何指针 -- object 或函数——在你的目标文件中。
换句话说,使用dlsym
的代码本质上是不可移植的,因为它不能广泛移植,因为它“仅”移植到所有指针都可以安全地相互转换的那些机器。 (当然,这几乎是当今所有流行的机器。)
所以,是的,您需要转换指针以使警告静音,这样做可能会使您的代码难以移植到所有指针都不相同的机器(以及警告,如果未静音) , 会正确地通知您您的代码将无法运行),但是无论如何 dlsym
永远不会在那些机器上运行(甚至以其当前形式存在)。
(如果 gcc -pedantic
警告您甚至从 void *
显式转换为函数指针类型,除了切换到不同的类型之外,您无能为力gcc
的版本,或者当然不要使用 -pedantic
。)
附录:我的回答听起来好像在指向不同类型数据的指针之间进行转换可能是个问题,但这通常没有问题。类型 void *
被很好地定义为通用数据指针:它是 malloc
返回的内容,并且它被定义为可以安静地转换为任何对象指针类型——也就是说,你甚至不需要类型转换。所以对于 dlsym
的返回类型,它几乎是一个不错的选择,except 对于函数指针的小问题。 malloc
从来没有这个问题(你几乎不会尝试 malloc 一个指向函数的指针),而 dlsym
总是有这个问题(你通常试图在动态加载的目标文件中访问代码至少与访问数据一样频繁)。但是函数指针是 void *
不能保证转换成的,所以你很可能会收到警告,这就是你需要强制转换的原因,你可能会在 下收到警告 -迂腐
,即使有类型转换也是如此。
关于使用 dlsym() 时进行转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31526876/
是否可以使用 dlsym 从框架加载已命名的未导出符号? ? 我尝试导入的符号有一个名称,在框架内引用它。这是我需要调用的函数。 我正在尝试照常进行 dlopen + dlsym方式,但是当我尝试加载
我收到此链接器错误: system/core/libacc/tests/main.cpp:42: error: undefined reference to 'dlsym' 您能告诉我 ubuntu
我使用 dlsym() 来调用我的 malloc 版本,而不是默认库 malloc: lt_malloc = (void*(*)(size_t))dlsym(RTLD_NEXT, "malloc")
1).直接打印函数地址: printf("strerror=%p, strerror_r=%p\n", strerror, strerror_r); strerror=0x8049ec0, strer
所以我一直试图从本地 dylib 获取符号,但每当我尝试做任何事情时,我都会遇到段错误,我不确定为什么会发生这种情况。我已经在其他程序中看到过这样做并且它们工作正常,所以我知道它有效但我似乎无法做到:
我真的很讨厌在这里提问。但我一直在看some of the other posts ,并且诸如此类的解决方案似乎不起作用。这可能是我对语法的误解。 我正在改进我的一些旧代码。问题中的函数循环通过一些加
作为 malloc 包装器,我使用了这段经典的代码片段: #define _GNU_SOURCE #include #include #include void* malloc(size_t s
我正在用 C 编写一个插件应用程序,我正在使用 dlopen/dlsym 动态加载某些功能的“实现”。例如,我有以下指向函数的指针 struct cti_t* (*create)() = 0; 然后我
我使用 dlopen 在我的程序中加载 pthread 库,并使用 dlsym 获取处理程序到 pthread_create 和 pthread_join >. 如何确保两个处理程序的版本兼容?我不在
man page dlsym() 列表 *(void **) (&cosine) = dlsym(handle, "cos"); 作为转换 dlsym() 返回值的解决方法。 这里的*(void
我在 C 中使用 dlsym() 我有一个问题 dlsym() 的返回值是否应该显式转换或者它是否被正确地隐式转换。这是函数: double (*(compile)(void))(double x,
我有一个动态加载库的应用程序,它动态加载库... 在 Windows 中,我能够遍历所有加载的模块以查找我感兴趣的符号。不知道如何在 Unix/Linux 环境中执行此操作。我知道我可以对前两个符号使
奇怪的是 dlsym 可以从剥离的二进制文件中导入函数。 谁能告诉我为什么/怎么做? === FILE: a.c === int a1() { return 1; } int a2() { retur
我正在尝试使用 Qt 5.3.0 在 Linux Mint 17 中编译 C++ 程序。我已将以下行添加到 .pro 文件中: QMAKE_LFLAGS += -ldl -fPIC 我的程序使用了 d
我正在使用 POSIX dlopen/dlsym API 在运行时加载动态库,然后按名称从这些库中调用函数。 存储 dlsym 的结果在性能方面是个好主意吗?某处?或者 dlsym 是否已经进行了自己
有没有跑路的希望dlopen(NULL, ...)并为静态编译的二进制文件获取符号? 例如,使用以下代码,如果程序是动态编译的并且我使用 -rdynamic,我可以获得符号。 . $ gcc -o f
我正在从共享对象 (a.so) 调用函数。我使用 dlopen 加载 a.so 并使用 dlsym 加载映射函数。 int (*funcPtr)() = reinterpret_cast(dl
我正在尝试使用 dlsym() 在 libcrypto.so 文件中查找 connect 符号,并希望用我的方法替换此 connect 。 void * lib_orig_tols = dlopen
我想从我的共享库 (.so) 中访问一个类符号这是我需要做的正确方法吗? MyClass* pMyClass= (MyClass*)dlsym(phandle, "MyClass"); 如果这是正确的
dlsym为枚举值返回 null NSLog(@"%s",dlsym(RTLD_DEFAULT, "NSTextAlignmentCenter")); 输出 2014-01-28 13:07:04.2
我是一名优秀的程序员,十分优秀!