在C++中调用C函数需用extern "C"禁用名称修饰,确保C链接;同样,C++定义供C调用的函数也须用extern "C"声明。
在C++中调用C语言函数,关键在于解决C++的名称修饰(name mangling)问题。C++编译器会对函数名进行修饰以支持重载、命名空间等特性,而C编译器只使用原始函数名。使用 extern "C" 就是为了告诉C++编译器:“这部分函数名不要修饰,按C的方式链接”。
当你有现成的C头文件(如 math.h、stdio.h),或自己写的C库头文件(比如 utils.h),需要在C++中调用时,需确保函数声明被 extern "C" 包裹:
#ifdef __cplusplus
extern "C" {
#endif
void c_function(int x);
int another_c_func(const char* s);
ifdef __cplusplus
}
endif
这样在C++中直接 #include "utils.h" 就能安全调用。
extern "C" {
#include "legacy_c_header.h" // 假设它只有C函数声明,无C++语法
}
// 然后就可以调用其中的函数了
c_legacy_init();
c_legacy_process(data);
如果你在C++源文件里写了一个函数,希望让C代码也能调用它,必须用 extern "C" 声明其链接规范:
// mycppfunc.h
#ifdef __cplusplus
extern "C" {
#endif
void cpp_implementation(int value); // C可见的接口
ifdef __cplusplus
}
endif
// mycppfunc.cpp
#include "mycppfunc.h"
extern "C" void cpp_implementation(int value) {
// 实际C++实现(可使用std::vector、new等)
std::cout << "Called from C: " << value << std::endl;
}
注意:函数体内部可以自由使用C++特性,但签名必须是C兼容的(不能含引用、类类型、重载、模板等)。
即使头文件声明正确,链接阶段出错(如 undefined reference to 'xxx')往往是因为符号名不匹配:
成员函数 —— 不合法(C链接不支持this指针);不复杂但容易忽略。核心就一条:让声明和定义的链接规范严格一致,并确保C和C++两端对符号的理解完全相同。