将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 ++数据类型。
答案 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"
。