C++调用 C 函数与 C 结构指针参数

C++ call C function with C struct pointer parameter

本文关键字:指针 参数 结构 函数 调用 C++      更新时间:2023-10-16

如果我没记错的话。此代码应该有效。

#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 源代码(没有外部"C")。如何在不修改 C 部分的情况下使其按C++编译?

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

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

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

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

Init((Base*)&d); 

理想情况下,您需要将此指针滥用封装到最小的可维护函数或类套件中。

你的Derived名字是误导性的。你不是从Base中推导出Derived,C 中的结构等价性并没有多大意义。它可以与 cast 一起使用,但您必须在没有任何编译器帮助的情况下保持这种等效性。当有一天你决定改变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);
}