extern "C"用于解决C++与C混合编程时的名字修饰冲突,确保C函数符号不被C++编译器修饰,从而实现正确链接;需在C++中用extern "C"包裹C头文件或函数声明,并保证C源文件用C编译器(如gcc)编译。

extern "C" 是用来解决名字修饰问题的
C++ 编译器会对函数名做 name mangling(名字修饰),比如把 void foo(int) 编译成类似 _Z3fooi 的符号;而 C 编译器只生成简单符号,如 foo。如果不加 extern "C",C++ 代码链接时就找不到 C 函数的真实符号,直接报 undefined reference to 'xxx' 错误。
在 C++ 中调用 C 库必须用 extern "C" 包裹声明
常见写法是:
extern "C" {
#include
#include "my_c_lib.h"
}
这样能让编译器知道:这些头文件里的函数名不要做 C++ 风格修饰。注意几点:
-
extern "C"只影响函数声明(即符号名),不影响实现——C 库的 .c 文件本来就是按 C 方式编译的 - 不能只包裹
#include,而漏掉你自己写的 C 函数声明;如果自己写了my_c_func()并在 .c 里实现,C++ 调用前也得用extern "C"声明它 - 如果 C 头文件本身已做了兼容处理(比如内部有
#ifdef __cplusplus),那可以不包,但多数第三方 C 库没这么做
extern "C" 不能用在类、模板、重载函数里
extern "C" 要求函数有唯一、无歧义的 C 风格链接名,所以:
Topsky 是一款针对中小型酒店设计的管理系统,基于 .Net Framework 4.5.2 设计,C# 语言编写,采用 SQL Server 2008 R2 数据库作为数据支持。
立即学习“C语言免费学习笔记(深入)”;
- 不能修饰 C++ 类成员函数(包括
static成员) - 不能修饰模板函数(实例化后名字不固定)
- 不能修饰重载函数(C 不支持重载,链接器无法分辨)
- 可以修饰
static全局函数,但仅限于本翻译单元内使用,对外不可见
链接时还要确保 C 库以 C 方式编译,不能用 g++ 编译 .c 文件
如果你自己写了个 utils.c,想被 C++ 调用,编译命令得分开:
- 用
gcc -c utils.c -o utils.o(不是g++)生成目标文件 - 再用
g++ main.cpp utils.o -o app链接 - 如果混用
g++ utils.c,即使加了extern "C"声明,utils.o里的符号仍是 C++ 修饰过的,链接仍失败
很多初学者卡在这一步:以为只要声明对了就行,其实编译阶段就得保持 C 的 ABI 一致性。










