将前向声明的C-struct定义为C ++ - struct

时间:2013-07-10 10:50:05

标签: c++ c forward-declaration

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接口获得一个外部可访问的opaque类型handle_t,它在内部实现为C ++数据类型。

2 个答案:

答案 0 :(得分:9)

是的,只要C代码永远不需要看到handle_tag结构的“内部”,并且C ++代码执行适当的C ++构造/销毁(我预先设置{{{ 1}}和construct适用于)。

C代码需要的只是指向某个数据结构的指针 - 它不知道内容是什么,因此内容可以是您喜欢的任何内容,包括构造函数/析构函数依赖数据。

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

EDIT2: 调用的C ++代码不会将异常“泄漏”到C代码中,这一点至关重要。这是未定义的行为,并且非常容易导致崩溃,或者更糟糕的是,“奇怪的事情”不会崩溃......所以除非保证代码不会导致异常(例如hold易于在内存不足的情况下抛出std::string,需要在C ++端的bad_alloc anf try/catch代码中使用construct块。

答案 1 :(得分:2)

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