我想用不同的签名为同一个函数发送回调。类似这样的事情:
#include <stdio.h>
#include <stdarg.h>
void a(int pa) {}
void b(int pb1, float pb2) {}
// exec implementation
int main() {
exec(a, 1);
exec(b, 1, 2.3);
}
我想到了使用类似这样的语句:
void exec(void (*func)(...), ...) {
int arg1;
float arg2;
va_list valist;
va_start(valist, size);
arg1 = va_arg(valist, int);
if (size == 1) {
(*func)(arg1);
va_end(valist);
return;
}
arg2 = va_arg(valist, float);
if (size == 2) {
(*func)(arg1, arg2);
va_end(valist);
return;
}
}
但很明显,这是行不通的:(
3条答案
按热度按时间pu82cl6c1#
为了使回调函数接口在提供给函数的数据方面具有灵活性,通常的解决方案是给予回调签名一个
void *
参数(可能还有其他参数)。通过这样的参数可以提供任意数据。类似于:然而,通过指定回调类型而不使用原型,可以实现与您描述的更相似的功能,其中回调函数确实具有不同的签名。在这种情况下,至少仍有以下警告:
float
s、short int
s或char
s如果你想支持其他的参数类型,那么你需要在调用函数之前转换函数指针,这将在后面描述。例如,可能如下所示:
这可能会引发一些警告,例如关于函数声明没有提供原型,以及关于调用(declared,but)非原型函数。但是,由于在执行调用时您已经知道了签名,因此可以通过适当的强制转换来消除后一种警告。例如,
0tdrvxhp2#
您可以更改回调以接受单个va_list参数:
并让另一个函数传递
va_list
。9w11ddsr3#
您可以使用
va_args
来解决这个问题。