我具有以下系统功能:
int sock_yield( void *s, void (*fn)() );
我需要传递一个带有2个参数的函数:
void reset(char buf,udp_Socket sock) {
if (-1 == udp_recv(&sock, &buf, sizeof(buf)));
if(buf=='R')
{
printf("\nReceived-> %c",buf);
forceSoftReset();
forceWatchdogTimeout();
}
}
在调用sock_yield
函数时,只能给它传递函数名称而不带参数:
sock_yield(sock, reset)
如何指定要传递给reset
的{{1}}的参数?
答案 0 :(得分:5)
您不能这样做。严格说来,在不同函数类型之间进行转换是未定义的行为,尽管某些编译器具有非标准扩展名,在某种程度上允许它。
此外,void (*fn)()
表示带有任何参数的函数,该函数已过时,样式为C,不应使用。
因此必须重写sock_yield
函数。如果要使用回调函数作为参数,那么它从一开始就很糟糕。它应采用一种特定的指定格式的函数指针。例如:
typedef void sock_callback_t (char buf, udp_socket* sock);
int sock_yield(void* s, sock_callback_t* fn);
或者,您可以编写一些技巧,在函数指针和uintptr_t
之间进行转换,但这是一个较差的解决方案,仅当您使用书写不良的API时才应使用。
答案 1 :(得分:1)
您不能。 C只知道函数的原始指针。然后,您可以在使用指针时提供所有必需的参数。示例:
int double(int i) {
return 2*1;
}
int exec_op(int param, int (*op)()) {
return op(param);
}
之所以可行,是因为在C中,无效参数列表意味着该函数可以接受任何参数。
如果在用例sock_yield
中调用不带参数的函数,则唯一的选择是使用带有全局参数的包装器:
char Buf;
udp_Socket Sock;
void reset_wrapper(void) {
reset(Buf, Sock);
}
,然后以这种方式使用它:
Buf = buf;
Sock = sock;
sock_yield(s, &reset_wrapper);