C ++使用C struct指针参数调用C函数

时间:2017-10-23 07:55:27

标签: c++

如果我没记错的话。这段代码应该有用。

#ifdef __cplusplus
extern "C" {
#endif

    typedef struct {
        int a;
    } Base;

    typedef struct {
        int a;
    } Derived;

    void Init(Base* b) {
        b->a = 1;
    }
#ifdef __cplusplus
}
#endif


int main() {
    Derived d;
    Init(&d); // error can not convert argument 1 from 'Derived *' to 'Base *'
}

它编译为C源(没有extern“C”)。如何在不修改C部分的情况下将其编译为C ++?

编辑:我修改了代码,以便它可以在C和C ++中实际复制和测试。

2 个答案:

答案 0 :(得分:4)

它在C中编译(同时生成警告),因为在C世界中更容易接受类型滥用。编制者通常允许违反标准。

在C ++中,您需要reinterpret_cast指针:

Init(reinterpret_cast<Base*>(&d)); 

Init((Base*)&d); 

理想情况下,您希望将此指针滥用封装到最小的可维护功能或类中。

答案 1 :(得分:2)

您的Derived名称具有误导性。您没有从Derived派生Base,而C中的结构等价并不重要。它可以与强制转换一起使用,但是你必须在没有编译器帮助的情况下保持这种等价。有一天你决定改变Base定义

typedef struct {
    int a;
    int c; /* New field */
} Base;

您必须修改所有“派生”定义。

在C中,导出通常是通过嵌入来模拟的:

#ifdef __cplusplus
extern "C" {
#endif

    typedef struct {
        int a;
    } Base;

    typedef struct {
        Base base;
    } Derived;

    void Init(Base* b) {
        b->a = 1;
    }
#ifdef __cplusplus
}
#endif

int main() {
    Derived d;
    Init(&d.base);
}