c++中extern C的作用是什么_c++调用C语言库【基础】

7次阅读

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

c++中extern C的作用是什么_c++调用C语言库【基础】

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 风格链接名,所以:

立即学习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 一致性。

text=ZqhQzanResources