' void *' to' void(*)(bool)'使用c ++编译器编译c中文件的指针错误

时间:2018-05-09 23:56:25

标签: c++ c function-pointers

首先,感谢所有正在阅读的人以及您可以回复的人。

这部分代码是接口库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

任何帮助,以及如何解决它的解释都将受到欢迎。

2 个答案:

答案 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 ++编译器编译代码,就可以了。