假设我有一个函数,它接受一个void (*)(void*)
函数指针作为回调:
void do_stuff(void (*callback_fp)(void*), void* callback_arg);
现在,如果我有一个这样的函数:
void my_callback_function(struct my_struct* arg);
我能安全地做这件事吗?
do_stuff((void (*)(void*)) &my_callback_function, NULL);
我看过this question,也看过一些C标准,它们说你可以转换成“兼容函数指针”,但我找不到“兼容函数指针”的定义。
发布于 2009-02-18 13:27:30
关键不在于你能不能做到。简单的解决方案是
void my_callback_function(struct my_struct* arg);
void my_callback_helper(void* pv)
{
my_callback_function((struct my_struct*)pv);
}
do_stuff(&my_callback_helper);
一个好的编译器只有在确实需要的时候才会为my_callback_helper生成代码,在这种情况下,你会很高兴它这样做了。
发布于 2009-02-18 02:19:10
当C代码编译成完全不关心指针类型的指令时,使用你提到的代码是很好的。当你用你的回调函数和指向其他东西的指针而不是my_struct结构作为参数来运行do_stuff时,你会遇到问题。
我希望我能通过展示什么是不起作用的来更清楚地说明:
int my_number = 14;
do_stuff((void (*)(void*)) &my_callback_function, &my_number);
// my_callback_function will try to access int as struct my_struct
// and go nuts
或者..。
void another_callback_function(struct my_struct* arg, int arg2) { something }
do_stuff((void (*)(void*)) &another_callback_function, NULL);
// another_callback_function will look for non-existing second argument
// on the stack and go nuts
基本上,只要数据在运行时继续有意义,您就可以将指针转换为您喜欢的任何内容。
发布于 2009-02-18 02:21:17
如果您考虑一下C/C++中函数调用的工作方式,它们会将某些项推入堆栈,跳转到新的代码位置,执行,然后在返回时弹出堆栈。如果您的函数指针描述的函数具有相同的返回类型和相同数量/大小的参数,则应该没问题。
因此,我认为您应该能够安全地这样做。
https://stackoverflow.com/questions/559581
复制相似问题