c 与 cpp 混合编译
为什么不能直接编译
必然不行,问题出现在编译的链接环节。
cpp 中有 c 没有的语法,如类、模板等等
cpp 有名字粉碎(name mangling)机制,和 c 编译器生成符号不同,这会导致链接(link)过程中出现
undefined symbol等错误如
void foo(int);,会被 cpp 编译成类似_Z4fooi的名字而 c 语言编译
void foo(int);后函数名还是foo
怎么办
用 .hpp 文件定义 cpp 语言,而 .h 需要适配 c,这样可以分开表示
在声明或 .h 中用 extern "C" 来转化所有需要通用的接口。
extern "C" 用法:
注意这个
"C"是大写的 C单行语句写法:
extern "C" void foo(int a);多行写法(一般写在 .h 中):
#ifdef __cplusplus extern "C" { #endif /* 你的头文件声明代码 */ #ifdef __cplusplus } #endif
如果是你想让 C 语言的 .h 文件能在 C++ 中使用,你需要用在这个头文件中用 extern "C" 把整个代码都括起开,这样 .cpp 文件在 include 这个头文件时就可以把他识别成 C 代码。
如果你想让 C++ 中的一部分代码能用在 C,在这部分代码前同样加 extern "C" 就可以了。但是你无法将 class 等强行变成 C 语言。
extern "C" int Foo(void){
// 正常的 C++ 代码
}
上面这个函数就可以被 C 语言用了(例如嵌入式用 freertos 时,你想用 C++ 写任务函数,这样就可以用了)
另外,C++ 某个变量或函数要是兼容 C,也要把 extern "C" 写到他的函数实现,他的所有声明也要有,总之一处用处处用,他在所有定义都要用 extern "C"
为什么我给C的头文件也要写
extern"C"?因为include不管你是什么文件,他的原理是复制,详见编译过程的宏处理阶段。另外
.h好多 C++ 也在用,所以你并不知道.h是谁的头文件。我还是倾向于把 C++ 的头文件写成.hpp。
vscode
感觉C和C++在一起用时,会有很多奇怪的问题,例如静态语法检查会报错,大概是vsc抽风罢(?)