How to mix C and C++
前言
最近在做的一个项目有大量遗留的C代码(legacy C code)。我尝试使用C++在原有基础上开发,并最终转换遗留的C代码。对于C和C++之间如何交互,我一直存有疑惑。我理解通过用extern“C”包装C代码,C ++编译器不会破坏C代码的名称,参考这个
在我的项目中,很多C的文件中都会有如下的写法
//include guards #ifndef _XXX_ #define _XXX_ #ifdef __cplusplus extern "C" { #endif others includes, typedefs, and function prototypes ... #ifdef __cplusplus } #endif #endif
我在自己的项目中搜__cplusplus,并没有找到他的定义,难不成是石头里蹦出来的?并不是,除了我们自己在项目中定义普通宏、带参宏外,gcc或者g++也会提供预定义宏(predefined macros),参考这个
在你的Linux主机上可以通过如下命令查看predefined macros
//For C gcc -dM -E - < /dev/null //For C++ g++ -dM -E -x c++ - < /dev/null //__cplusplus就是这么定义的 root@ubuntu:~# g++ -dM -E -x c++ - < /dev/null | grep __cplusplus #define __cplusplus 199711L
本文将介绍C/C++混合编程相关技术。具体内容以问题的方式展开
如何理解 extern "C"
extern "C"
doesn't really change the way that the compiler reads the code. If your code is in a .c file, it will be compiled as C, if it is in a .cpp file, it will be compiled as C++ (unless you do something strange to your configuration).
What extern "C"
does is affect linkage. C++ functions, when compiled, have their names mangled -- this is what makes overloading possible. The function name gets modified based on the types and number of parameters, so that two functions with the same name will have different symbol names.
Code inside an extern "C"
is still C++ code. There are limitations on what you can do in an extern "C" block, but they're all about linkage. You can't define any new symbols that can't be built with C linkage. That means no classes or templates, for example.
We don't put this wrapper around the .c files, just the .h files. So, what happens if a function doesn't have a prototype? Does the compiler think that it's a C++ function?
unctions without prototypes will have C++ linkage if they are in .cpp files and not inside of an extern "C"
block. This is fine, though, because if it has no prototype, it can only be called by other functions in the same file, and then you don't generally care what the linkage looks like, because you aren't planning on having that function be called by anything outside the same compilation unit anyway.