我很难将void*
函数传递给它的参数void*
:
#include <stdlib.h>
void* hello(void* (*calc)(void *), void* op){
int val = *(int *) op;
int* retval = malloc(sizeof(int));
*retval = calc(val);
return retval;
}
int calc(int b){
int a = 5;
int sum = a+b;
return sum;
}
int main(){
int arg = 4;
int value = *(int*) hello(&calc,&arg);
return 0;
}
错误是:
40392282.c: In function ‘hello’: 40392282.c:6:20: warning: passing argument 1 of ‘calc’ makes pointer from integer without a cast [-Wint-conversion] *retval = calc(val); ^~~ 40392282.c:6:20: note: expected ‘void *’ but argument is of type ‘int’ 40392282.c:6:13: warning: assignment makes integer from pointer without a cast [-Wint-conversion] *retval = calc(val); ^ 40392282.c: In function ‘main’: 40392282.c:19:31: warning: passing argument 1 of ‘hello’ from incompatible pointer type [-Wincompatible-pointer-types] int value = *(int*) hello(&calc,&arg); ^ 40392282.c:3:7: note: expected ‘void * (*)(void *)’ but argument is of type ‘int (*)(int)’ void* hello(void* (*calc)(void *), void* op){ ^~~~~ 40392282.c:19:9: warning: unused variable ‘value’ [-Wunused-variable] int value = *(int*) hello(&calc,&arg); ^~~~~
有关如何将函数实际传递为类型为void*
的参数的任何建议吗?
谢谢@ 2501,但我收到以下错误。
hello.c: In function ‘hello’:
hello.c:12:18: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
int(*calc)(int) =calc_call;
^
hello.c: In function ‘main’:
hello.c:34:35: warning: passing argument 1 of ‘hello’ from incompatible pointer type [-Wincompatible-pointer-types]
int value = *(int *) hello(&calc,&arg);
^
hello.c:10:7: note: expected ‘void * (*)(void *)’ but argument is of type ‘int (*)(int)’
void* hello(void* (*calc_call)(void *), void* op){
当我编写代码时:
void* hello(void* (*calc_call)(void *), void* op){
int* const integer = op;
int(*calc)(int) =calc_call;
*integer=calc(*integer);
return op;
}
int calc(int b){
int a = 5;
int sum = a+b;
return sum;
}
int main(){
int arg = 4;
int value = *(int*) hello(&calc,&arg);
return 0;
}
答案 0 :(得分:0)
首先,我想说你正在做的事情非常非常糟糕。您正在转换一个函数,该函数接受并返回一个函数,该函数接受并返回一个void *,然后在函数内(hello)将返回值保存为int *,并继续返回int * cast to一个void *,你最终将它强制转换为int(不释放内存,我可以添加)。
您需要知道的第一件事是您可以将任何内容转换为void指针。这是人们偏离它们的原因之一。就个人而言,我喜欢玩hacky代码并尝试解决问题,也许这就是你正在做的事情。但请,请不要在任何项目或工作中包含此类代码,特别是如果您正在合作。
现在,回到无效指针。任何东西都可以是一个无效指针。我不能强调这一点。例如,
int *****arr; // 5D array
void* arr_ptr = (void*)arr;
完全有效(但不是很好)代码。您还可以将非指针类型强制转换为void指针。
调用函数: int *value = (int*) hello( (void* (*)(void*))calc, (void*)arg );
您需要将函数和参数强制转换为正确的指针类型。请注意,我不使用&calc
或&arg
,因为我们不需要。请记住,我们可以将任何内容转换为void *,如果我们不需要,为什么还要处理引用和解除引用? calc的强制转换可以简化为(void*)calc
,我只需使用上面的完整演员来清楚说明发生了什么。
你好功能
void* hello(void* (*func)(void *), void* op)
{
int* retval = malloc(sizeof(*retval));
*retval = (int)func(op);
return retval;
}
我在这里更改的是函数的名称(您不希望将函数指针命名为与实际函数相同的名称,它可能会产生意外结果)。
如果您希望代码可以移植到不同类型,我建议稍微修改一下:
void* hello(void* (*func)(void *), void* op, int size)
{
void** retval = malloc(size);
*retval = func(op);
return retval;
}
并从主处调用它:
int *value = (int*) hello((void*)calc, (void*)arg, sizeof(int));
aditional参数指定函数将返回sizeof(int)
个字节,因此您知道正在获取正确数量的数据。
最后,在你的主文件中你不应该立即取消引用指针,而是取值并释放内存,以避免内存泄漏。
答案 1 :(得分:0)
您的代码有几个错误,但一个是关键的:将函数指针转换为不兼容的类型并调用它。调用参数calc时,函数hello会发生这种情况,参数calc的类型void*(*)(void*)
由不兼容的类型int(*)(int)
转换而来。
此调用将导致未定义的行为。
传递函数指针的正确解决方法是使用正确的类型,
在这种情况下:int(*)(int)
。
不需要分配内存,因为对函数指针的调用的返回值可以存储在同一个变量中:
void* hello( int( *calc)( int ) , void* op )
{
int* const integer = op ;
*integer = calc( *integer );
return op;
}
如果你坚持在函数hello中使用类型void*(*)(void*)
作为第一个参数,那么你必须将参数转换回正确的类型:
void* hello( void*( *calc )( void* ) , void* op )
{
int* const integer = op ;
int ( *correct )( int ) = ( ( int )( * )( int ) )calc;
*integer = correct( *integer );
return op ;
}