C++ Academy · 课时

Extern C 与 C ABI

使用 extern C 从 C++ 库公开兼容 C 的接口

第 1 / 4 课14 个步骤

Extern C 与 C ABI 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。

为什么需要互操作

C++ 具有复杂的 ABI(应用程序二进制接口),包括名称修饰、异常和模板。其他语言(C、Python、Rust)无法直接使用经过修饰的 C++ 符号。

extern "C"

请将声明包裹在 extern "C" 中,以禁用 C++ 名称修饰并使用 C 调用约定。

extern "C" {
    void greet(const char* name);
    int add(int a, int b);
}

为什么使用 C ABI

C ABI 是各种语言之间的最低公分母。几乎所有语言都可以通过 FFI 调用 C 函数。

头文件模式

通过条件式 extern "C",让一个头文件同时可供 C 和 C++ 使用。

#ifdef __cplusplus
extern "C" {
#endif

void hello(void);
int sum(int a, int b);

#ifdef __cplusplus
}
#endif

无法导出的内容

某些 C++ 特性在 C 中没有对应形式:

  • 类(C 中没有类的概念)
  • 模板(在编译时解析,无法导出)
  • 重载函数(没有名称修饰,就无法实现重载)
  • 异常(必须在跨越 FFI 之前捕获)

公开类

请使用不透明指针和 C 风格 API 隐藏类的实现。

// header (C visible)
typedef struct Widget Widget;
Widget* widget_create(int x);
void    widget_destroy(Widget*);
int     widget_value(const Widget*);

// .cpp
class WidgetImpl { /* ... */ };
extern "C" {
    Widget* widget_create(int x) { return reinterpret_cast<Widget*>(new WidgetImpl(x)); }
    void widget_destroy(Widget* w) { delete reinterpret_cast<WidgetImpl*>(w); }
}

避免跨 FFI 传递异常

通过 C 调用的 C++ 函数如果抛出异常,程序将中止。请在边界处捕获异常。

extern "C" int safe_call() {
    try {
        risky();
        return 0;
    } catch (...) {
        return -1;
    }
}

内存所有权

请明确记录每项资源的所有者——通常由分配资源的一方负责释放。所有权不匹配会导致内存泄漏或重复释放。

跨 FFI 传递字符串

std::string 仅属于 C++。跨 FFI 传递时请使用 const char*。请决定接收方是否复制字符串,并记录其生命周期。

跨 FFI 传递结构体

请使用在 C 和 C++ 中具有相同布局的 POD(普通旧数据)结构体。避免使用虚函数、引用或标准库类型。

回调

请通过 FFI 传递函数指针(或 void* 加函数指针)。请为闭包提供上下文指针。

extern "C" {
    typedef void (*Callback)(int value, void* user_data);
    void register_callback(Callback cb, void* user_data);
}

链接方式和头文件

extern "C" 只影响链接方式,不影响行为。函数仍会在 C++ 环境中编译,但可以从外部作为 C 函数调用。

快速检查

将 C++ 函数公开给其他语言时,为什么要将其包裹在 extern "C" 中?

回顾

extern "C" 为函数提供 C 链接方式——不进行名称修饰,并使用 C 调用约定。请通过 FFI 使用它将 C++ 公开给其他语言。请使用不透明指针隐藏类,在边界处捕获异常,并清楚记录所有权。

免费开始

用 AI 导师学习 C++ — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
51
课程
203

常见问题解答

「Extern C 与 C ABI」课时是免费的吗?

是的 — 「Extern C 与 C ABI」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。

「Extern C 与 C ABI」这节课中我会学到什么?

使用 extern C 从 C++ 库公开兼容 C 的接口 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C++ Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「Extern C 与 C ABI」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C++ Academy 课中编写并运行代码吗?

能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Extern C 与 C ABI
  2. 通过 pybind11 从 C++ 调用 Python
  3. 面向 Rust FFI 边界的 C++
  4. 使用 SWIG 生成多语言绑定
← 返回 C++ Academy