首先,感谢所有正在阅读的人以及您可以回复的人。
这部分代码是接口库gui的一部分,完全用c。
编写但是我很想在c中编译这些写入的文件,用c ++编译器能够集成到我用wxwidgets做的程序中。
在c文件中,我有几个函数调用,它们作为参数,指向其他函数的指针。
typedef struct {
void (*fchd_ptr)(bool);
uint16_t xpos;
uint16_t ypos;
...
...
}BUTTON_t;
void BT_SetHandler(BUTTON_t* ptr, void* fchd_ptr)
{
if (ptr == NULL)
return;
ptr->fchd_ptr = fchd_ptr; // OK in C, ERROR In C++
}
当我尝试用C ++编译时,我得到了这个错误。
ptr-> fkt_ptr = fkt_ptr;
// error: invalid conversion from 'void *' to 'void (*) (bool)' [-fpermissive]
如果我施放了明确的演员。
ptr-> fkt_ptr = (bool *) fkt_ptr;
// error: can not convert 'bool *' to 'void (*) (bool)' in assignment
任何帮助,以及如何解决它的解释都将受到欢迎。
答案 0 :(得分:1)
你的明确演员是错误的。你强制转换为bool *
(指向bool
类型的对象的指针),当你真的应该转向void (*)(bool)
时(指向函数的指针取bool
并且什么都不返回)。< SUP> 1
如果用
替换该行ptr->fchd_ptr = (void (*)(bool)) fchd_ptr;
它将在C和C ++中编译。
但是,如果可能的话,你应该尝试用C编译你的C代码 - 虽然我们可能会让这一件事工作,但这两种语言并不总是完全兼容,你可能会遇到麻烦。通常,可以从C ++部分单独编译C代码。如果在头文件中使用extern "C"
,则只需将C ++对象和C对象链接在一起,或将C部分保存在单独的库中(静态或动态)。
另外,我建议重新编写C API,这样如果可能的话,它确实需要一个函数指针。通过void *
进行别名是很丑陋的,如果传入错误的指针类型,可能会导致一些非常讨厌的错误和崩溃。
1 函数指针通常与对象指针非常不同,它是实现定义的,你是否允许在两者之间进行转换。在这里,您需要一个指向函数的指针,而不是指向对象的指针(如bool*
将是指向bool
类型的对象的指针),以便您以后可以调用它。您可以在代码示例中看到void (*fchd_ptr)(bool)
是您分配给的变量的声明,这使void (*)(bool)
成为其类型。如果你发现这种符号有些令人困惑,cdecl.org是处理那些来自C的复杂数组,指针和函数指针名称的好方法。
答案 1 :(得分:1)
如果更改函数的签名以接受与ptr->fchd_ptr
期望的类型匹配的函数指针。然后,您不需要使用强制转换来完成作业。
根据您的问题,这将是:
void BT_SetHandler(BUTTON_t* ptr, void (*fchd_ptr)(bool))
但是,如果您不确定ptr->fchd_ptr
的类型是什么,您可以让编译器为您解决问题。以前,这只能通过模板函数完成,它将根据在编译时传递给函数调用的内容派生出一个类型。但是,C ++。11证明decltype
,它允许你强制执行函数参数所需的类型,而不是让编译器从函数的调用者中推导出一个。
void BT_SetHandler(BUTTON_t* ptr, decltype(ptr->fchd_ptr) fchd_ptr)
只要您打算使用C ++编译器编译代码,就可以了。