【发布时间】:2020-11-22 04:03:07
【问题描述】:
从这里:ISO C Void * and Function Pointers,我找到了将(void*) 转换为函数指针的解决方法:
int
main(int argc, char *argv[])
{
...
void (*funcp)(void); /* Pointer to function with no arguments */
...
*(void **) (&funcp) = dlsym(libHandle, argv[2]);
}
换句话说 - 取消引用双指针(另一个间接级别)。
现在仍然假设最终函数是 void(*)() 类型,但我想让转换可用于其他函数“类型”,例如可以接受一些参数。
然后我找到了另一种解决方法,如何将函数指针包装在 struct Why can't I cast a function pointer to (void *)? 中:
typedef struct
{
void (*ptr)(void);
} Func;
Func vf = { voidfunc };
所以我想合并这两个想法,并可以通过 struct 将任意函数类型作为函数指针传递:
#include <stdio.h>
struct s{
int a, b;
void (*func)();
};
typedef struct{
int (*add)(int,int);
} Func;
int add(int a, int b) { return a+b; }
int main(){
Func f = {add};
struct s foo = {.func=(void*)(&f)};
printf("%i\n",f.add(1,2));
printf("%i\n",foo.func(1,2));
}
不幸的是,它给出了错误:
invalid use of void expression
所以问题是,如何在printf 语句中将类型(void*) 转换为(int*)(int,int)?
【问题讨论】:
-
即使你改变了编译指针,它也永远不会工作。
-
关于“我找到了转换的解决方法”:也许您的意思是您找到了转换的解决方法。强制转换是执行转换的运算符,您不需要变通方法将
void *强制转换为函数指针,因为您只需编写强制转换:void (*funcp)(void) = (void (*)(void)) dlsym(libHandle, argv[2]);。 C 标准没有定义,但允许。如果您在支持dlsym的环境中工作,据记录返回void *是代码或数据的地址,那么该环境必然支持将void *转换为... -
… 一个函数指针。它隐含地是与该环境一起使用的编译器的一部分(尽管这应该在文档中明确说明;使其隐含是低于标准的工程)。此外,如果 C 实现确实支持将
void *转换为函数指针,它将通过简单的强制转换来实现——不太可能有任何实现不支持它,而是通过重新解释指针的位来支持它。是做。这增加了表示和别名的其他问题。 -
您可以将
dlsym的返回值转换为适当的函数指针类型。我不明白你想用这些结构做什么,但它看起来像一个XY problem。 -
Re “那么问题来了,如何将
(void*)类型转换回(int*)(int,int)?在 printf 语句中?”:不要那样做。没有理由这样做。要打印任何指针,请使用%p,而不是%i,并将其转换为void *(如果还没有的话)。
标签: c pointers casting function-pointers void-pointers