我需要在处女ANSI C(1989)中解决一个问题。
我有一些指针(void * func)用于(int n)双参数,并且数组double values[]
带有n
个数字。所以我想用n
param运行我的函数,它位于value中。
例如,我有功能:
double hypotenuse(double x, double y, double z);
所以
void *func = (void *)hypotenuse; double values[3] = {5, 4, 3}; int n = 3;
我想做这样的事情:
func(n, values);
问题是我无法改变功能的原型, 所以我需要以某种方式这样做(也许是一些宏?)。
答案 0 :(得分:4)
主要问题是你必须根据参数的数量(即取决于n
变量)对指针进行不同的投射。
一种方法是使用包含switch
语句的包装函数作为参数号:
double wrapper(void *func, double args[], int n)
{
switch (n)
{
case 0:
return ((double (*)(void)) func)();
case 1:
return ((double (*)(double)) func)(args[0]);
case 2:
return ((double (*)(double, double)) func)(args[0], args[1]);
case 3:
return ((double (*)(double, double, double)) func)(args[0], args[1], args[2]);
default:
printf("Error: wrapper called with %d arguments\n", n)
break;
}
return 0.0;
}
答案 1 :(得分:2)
昨晚写的很晚 - 但是当我尝试发布时,我的互联网连接失败了。我看到约阿希姆写的答案基本相同。
在限制范围内,这将有效:
#include <assert.h>
extern double function_invoker(void *func, int n, double *values);
double function_invoker(void *func, int n, double *values)
{
switch (n)
{
case 0:
return (*(double (*)(void))func)();
case 1:
return (*(double (*)(double))func)(values[0]);
case 2:
return (*(double (*)(double, double))func)(values[0], values[1]);
case 3:
return (*(double (*)(double, double, double))func)(values[0], values[1], values[2]);
default:
assert("Need more entries in the switch in function_invoker()" == 0);
return(0.0);
}
}
明显的限制是您要在switch
中输入多少条目。我已经看到松散类似的代码超过100个参数;我不确定为什么认为这是必要的。
该代码在Mac OS X 10.8.2的GCC 4.6.0下编译时没有警告:
$ gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition -c x.c
$
但如果你选择double (*)()
代替void *
,你会得到:
$ gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition -c x.c
x.c:3:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
x.c:5:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
$