void funcPtr(int a);
int main(){
int k=1;
void (*funcPtr2)(int);
funcPtr2 = (void*)(funcPtr);
// funcPtr2 = (void(*)(int))(funcPtr);
(*funcPtr2)(k);
return 0;
}
void funcPtr(int a){
printf("%d", a);
}
函数指针类型转换中(void*)
和(void(*)(argument type)
之间的区别是什么?
因此,它不会发出警告。
这是错的吗?关于(void*)
类型转换
答案 0 :(得分:7)
这是错的吗? about(void *)类型转换
是的,是的。
C标准不允许将函数指针转换为对象指针或它们之间的赋值。如果您提高了编译器警告级别,则可能会收到警告/错误,例如编译:
gcc -Wall -Wextra -pedantic-errors -std=c11 file.c
我不确定你为什么要考虑转换函数指针。如果函数指针类型与函数匹配,只需指定它:
funcPtr2 = funcPtr;
除了:
您可以像使用函数一样使用函数指针:
funcPtr2(k);
并使用main
的标准原型,例如:
int main(void)
答案 1 :(得分:1)
这是dlsym
的问题,声明为void *dlsym(void *restrict handle, const char *restrict name)
。 dlsym
返回指向name
中定义并可通过handle
访问的名为gcc
的函数的指针
然而,正如@BlueMoon所述,这在ISO C中没有定义,fptr = (int (*)(int))dlsym(handle, "my_function");
确实抱怨如果迂腐。 POSIX试图解决这个问题,并要求符合要求的实现,以使其无限期地定义良好的定义。
来自POSIX
请注意,从void *指针转换为函数指针,如:
void**
未由ISO C标准定义。该标准要求此转换在符合要求的实现中正常工作。
使该转换符合的另一种方法是首先将函数指针转换为void funcPtr(int a); /* symbol to extract */
int main(void)
{
void (*fn)(int);
*(void**)(&fn) = dlsym(your_handle, "funcPtr");
fn(5);
}
,然后取消引用它。这应该是明确的。
在你的情况下,
\r\n
答案 2 :(得分:0)
(void*)
将指针转换为指向void 的指针,或指向通用指针。
void(*)(int)
是一个函数指针,它指向一个带有int参数且不返回任何内容的函数。
int fn(float f) { return f * 3.14; }
void* ptr = fn;
将ptr
设为fn
的第一条机器指令的地址,但不允许您使用它。
int(*ptr)(float) = fn;
// or
typedef int(FnPtr)(float);
FnPtr* ptr = fn;
以编译器知道指向哪种函数调用的方式获取地址,以便您可以调用函数
int n = ptr(2.5);
对于像
这样的事情有用void get_data(int socket, int timeout, void(*callback)(char*, size_t));
这是一个我可以传递另一个函数的函数。
void recv_data(char* data, size_t len)
{
...
}
...
get_data(socket, 60, recv_data);