1. 什么是 extern "C"
?
作用
extern "C"
是 C++ 提供的关键字,用于告诉编译器按照 C 语言方式编译和链接函数或变量,以解决 C++ 名称修饰(Name Mangling) 带来的兼容性问题。
2. 为什么需要 extern "C"
?
C++ 名称修饰(Name Mangling)问题
-
C++ 支持函数重载,所以编译器会在编译时修改函数名,加入参数类型信息。
-
C 语言不支持重载,其函数名在编译后不会被修饰。
示例(C++ 代码编译后):
void func(int); // 可能变为 _Z4funci
void func(double); // 可能变为 _Z4funcd
// dumpbin /SYMBOLS main.obj | find "func"
如果 C++ 直接调用 C 语言函数(没有 extern "C"
),链接时找不到匹配的名称,会报 undefined reference
错误。
3. extern "C"
的使用方式
(1)C++ 调用 C 语言代码
C 语言文件(c_lib.c):
#include <stdio.h>
void c_function() {
printf("This is a C function\n");
}
C 头文件(c_lib.h):
#ifndef C_LIB_H
#define C_LIB_H
#ifdef __cplusplus
extern "C" {
#endif
void c_function();
#ifdef __cplusplus
}
#endif
#endif
C++ 代码(main.cpp):
#include "c_lib.h"
int main() {
c_function(); // 成功调用 C 语言函数
return 0;
}
关键点:
-
头文件使用
extern "C"
避免 C++ 进行名称修饰(Name Mangling)。 -
#ifdef __cplusplus
使得 C 语言代码也能包含此头文件,不会出错。
(2)C 语言调用 C++ 代码
C++ 代码(cpp_lib.cpp):
#include <iostream>
extern "C" void cpp_function() {
std::cout << "This is a C++ function\n";
}
C 代码(main.c):
#include <stdio.h>
void cpp_function(); // 直接声明
int main() {
cpp_function(); // 成功调用 C++ 函数
return 0;
}
解析
-
C 语言不能直接识别
extern "C"
,但 C++ 端定义函数时必须加extern "C"
,这样 C 语言才能正常链接。
4. extern "C"
适用于哪些情况?
✅ 适用于
-
函数
extern "C" void func();
-
多个函数
extern "C" { void func1(); void func2(); }
-
变量
extern "C" int global_var;
-
整个头文件(推荐做法)
#ifdef __cplusplus extern "C" { #endif void func(); #ifdef __cplusplus } #endif
❌ 不适用于
-
C++ 类(C 语言不支持类)
-
函数重载(C 语言不支持重载)
5. extern "C"
的实际应用场景
(1)C++ 调用 C 库(如 OpenCV、FFmpeg)
extern "C" {
#include <opencv2/opencv.hpp>
}
(2)封装 C 接口,提供给 Python、Rust 等其他语言使用
extern "C" int add(int a, int b) {
return a + b;
}
(3)跨语言混合编程(C 与 C++ 混合)
-
嵌入式开发
-
操作系统开发
6. extern "C"
相关注意事项
✅ 正确使用方式
✔ extern "C"
只能用于 全局作用域,不能嵌套到局部变量或函数内部。 ✔ 用 #ifdef __cplusplus
确保头文件可在 C 和 C++ 两端兼容。 ✔ 适用于 函数和变量,但不能用于 类和重载函数。
⚠️ 常见错误
❌ 错误示例:使用 extern "C"
修饰 C++ 类
extern "C" class Test { // ❌ C++ 类不能加 extern "C"
int x;
};
❌ 错误示例:使用 extern "C"
修饰重载函数
extern "C" void func(int); // ✅ 可用
extern "C" void func(double); // ❌ 不支持重载
7. 总结
特性 | 描述 |
---|---|
作用 | 让 C++ 代码调用 C 语言代码,避免名称修饰 |
原理 | 关闭 C++ 的 Name Mangling,使 C++ 符号与 C 语言兼容 |
常见用法 | extern "C" {} 包围 C 语言函数声明 |
适用范围 | 函数、变量,但 不能用于类或函数重载 |
常见应用 | 调用 C 语言库(如 OpenCV、FFmpeg),C++ 代码被 C 语言调用 |
extern "C"
是 C++ 和 C 语言混合编程的关键工具,使两种语言可以互相调用,提高代码的可扩展性和兼容性。
视频链接:
关注微信公众号 程序员陈子青 解锁你的高薪offer之旅。