将正向声明的C结构定义为C++结构

Define forward declared C-struct as C++-struct

本文关键字:结构 定义 C++ 声明      更新时间:2023-10-16

struct转发声明为C-struct 合法吗

// api.h
#ifdef __cplusplus
extern "C" {
#endif
    typedef struct handle_tag handle_t;
    handle_t *construct();
    void destruct(handle_t *h);
    void func(handle_t *h);
#ifdef __cplusplus
}
#endif

并随后将其定义为C++-struct,即非POD类型?

// api.cpp
struct handle_tag {
    void func();
    std::string member;
};
void func(handle_t *h) {
    h->func();
}

一般目的是通过C接口获得一个外部可访问的不透明类型handle_t,该类型在内部实现为C++数据类型。

是的,只要C代码永远不需要看到handle_tag结构的"内部",并且由C++代码执行适当的C++构建/销毁(我预设constructdestruct是用于此结构的),就可以正常工作。

C代码所需要的只是一个指向某些数据结构的指针——它不知道内容是什么,所以内容可以是你想要的任何内容,包括依赖构造函数/析构函数的数据。

编辑:我应该指出,这或类似的方法(例如,使用void *将C部分的对象地址记录到hold)是将C代码接口到C++功能的一种相当常见的方式。

第2版:至关重要的是,被调用的C++代码不会将异常"泄漏"到C代码中。这是一种未定义的行为,很容易导致撞车,或者更糟的是,不会撞车的"奇怪的事情"。。。因此,除非保证代码不会引起异常(例如,在内存不足的情况下,std::string可能会抛出bad_alloc),否则需要在代码内部使用try/catch块,如C++侧的constructfunc

不能按原样工作,但概念还可以。当函数被定义时,您还需要确保名称没有被破坏,以便C代码可以找到它们。这意味着#include "api.h"应该添加到api.cpp文件的顶部。