extern "C"用于解决C++与C混合编程时的链接问题,通过禁用C++的名字修饰机制,确保函数按C语言规则编译链接。在C++中调用C函数或让C调用C++函数时,需用extern "C"声明接口函数,并避免使用C++特有类型和语法,以实现跨语言正确链接。

在C++程序中使用extern "C"的主要作用是解决C++与C语言混合编程时的链接问题。C++支持函数重载和类等特性,因此在编译时会对函数名进行**名字修饰(name mangling)**,而C语言编译器不会对函数名做类似处理。这会导致C++代码调用C编译生成的函数,或C代码调用C++函数时出现“找不到符号”的链接错误。
extern "C" 的作用
extern "C" 告诉C++编译器:这部分函数或变量应按照C语言的规则进行编译和链接,即不进行名字修饰。这样可以确保C++代码能正确调用C语言编写的函数,也能让C代码调用被正确导出的C++函数(前提是这些函数以C方式链接)。
常见用法如下:
extern "C" {
void my_c_function(int x);
int add(int a, int b);
}
上面的写法表示这两个函数使用C语言的链接规范。如果头文件可能被C++程序包含,通常会加入宏判断:
立即学习“C语言免费学习笔记(深入)”;
#ifdef __cplusplus
extern "C" {
#endif
void my_c_function(int x);
int add(int a, int b);
#ifdef __cplusplus
}
#endif
这样既兼容C编译器,也兼容C++编译器。
C与C++混合编程的链接问题及解决方案
当在一个项目中同时使用C和C++源文件时,链接阶段可能出现“undefined reference”错误,原因就是函数名在目标文件中的符号名称不一致。
解决方法包括:
-
在C++中调用C函数:确保C函数的声明被
extern "C"包围,并且C代码由C编译器编译(如gcc),C++代码由g++编译。 -
在C中调用C++函数:必须将被调用的C++函数用
extern "C"声明,并且该函数不能是类成员函数或重载函数(因为C不支持这些特性)。 - 避免C++特性暴露给C代码:传递参数时使用C兼容的数据类型,如基本类型、结构体(不含构造函数等)、指针等,避免直接传std::string或类对象。
示例:在C++中定义一个可被C调用的函数:
// cpp_func.cpp #includeextern "C" void greet_from_cpp() { std::cout << "Hello from C++!" << std::endl; }
C代码中声明并调用:
// main.c
extern void greet_from_cpp(); // 声明为C链接
int main() {
greet_from_cpp();
return 0;
}
编译命令示例:
g++ -c cpp_func.cpp -o cpp_func.o gcc main.c cpp_func.o -o program
这样就能成功链接并运行。
总结
extern "C" 是实现C与C++互操作的关键机制,它控制函数的链接方式,避免因名字修饰导致的链接失败。在混合编程中,合理使用extern "C",并注意接口层的数据类型和函数设计,是确保模块间正常通信的基础。
基本上就这些。只要理解了名字修饰和链接规范的区别,这类问题就不难解决。











