8

将 a 前向声明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++ 数据类型。

4

2 回答 2

9

是的,只要 C 代码永远不需要看到handle_tag结构的“内部”,并且适当的 C++ 构造/破坏由 C++ 代码执行(我假设constructanddestruct是为了),它就可以正常工作。

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

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

Edit2:至关重要的是,调用的 C++ 代码不会将异常“泄漏”到 C 代码中。这是未定义的行为,很容易导致崩溃,或者更糟糕的是,不会崩溃的“奇怪的事情”......所以除非代码保证不会导致异常(例如,在低的情况下std::string可能会抛出bad_alloc内存),需要在 C++ 端使用try/catchconstructanf这样的代码块。func

于 2013-07-10T10:54:24.287 回答
2

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

于 2013-07-10T11:16:46.007 回答