凡亿专栏 | C与C++混合编程
C与C++混合编程

    这篇文章讲解的知识点很“小”,但是在C和C++的混合编程中非常重要。因为我们在写应用程序时,经常利用到第三方的程序。如果我们的代码用C,但是第三方代码是C++;或者我们的代码用C++,而第三方的代码是C,那么在整合的时候就需要仔细一点了。


一、C调用C++中的函数


1. 被调用C++代码中的头文件(callee.h)

d7f6cee9c3aff33159514eff3220b3.png


2. 被调用C++代码中的源文件(callee.cpp)

676dd76ba053882f95ebf95b52b72a.png


3. 被调用C++代码编译成目标文件(callee.o)

7024b906d35b0b53e2c9ba49dff22c.png


知识点:

(1)关于 __cplusplus

    编译器使用g++,所有的C++编译器中都会定义宏:__cplusplus,因此在编译callee.h的时候,会把函数声明包裹在extern "C" 中。


(2)关于 extern "C"

    C和C++编译器,在编译一个函数的时候,编译策略是不同的。C++会对函数的名称进行改写(而且每个C++编译器对于名字改写的规则也是不一样的,甚至同一个编译器的不同版本的名字改写规则也不一样,因此,使用C++时最好用相同的编译器版本对项目中的所有模块进行编译。补充:改写的目的是为了实现C++语言中的函数重载)。


    在callee.h中,把函数 cpp_hello 放在 extern "C" 中,意思就是告诉编译器g++: 这个函数是需要被C调用的,请不要对这个函数进行名字改写。


    可以通过 nm 指令查看一下目标文件callee.o中的符号:

271cf777c841915e4b2030fd7e7125.png

    我们可以多做一个测试:把extern "C"去掉之后,看一下这个函数如何被g++改写了名字:

ae65736b142ec7f5e6ea6e13c43abc.png


4. 主调用C代码中的源文件(caller.c)

6e760d9376d69ee808f99568c21e23.png


5. 编译主调用C文件,得到可执行文件

ce7b2371322a433045bb2c8b28ec01.png


知识点:

(1)caller.c在 include “callee.h" 时,gcc编译器中没有定义 __cplusplus 宏,所以 callee.h 中就相当于只有一句话:void cpp_helo();


(2)在调用 cpp_hello()函数时,虽然这个函数是用g++编译的,但是由于使用了 extern "C",所以名字没有被编译器g++改写,也就是说,在callee.o目标文件中,函数的名字就是 "cpp_hello",所以可以顺利的被C代码调用到。


二、C++调用C中的函数

1. 被调用C代码中的头文件(callee.h)

77e21fcde02b7f737e463421be7ce9.png


2. 被调用C代码中的源文件(callee.c)

5aa626c82d3f1f07278f90e336b052.png


3. 被调用C代码编译成目标文件(callee.o)

4d5353ef2d2a4c49e6995638ba0da9.png


知识点:

    编译器使用gcc,其中没有定义宏:__cplusplus,因此在编译callee.h的时候,相当于只有一个函数声明。因此函数c_hello在被编译到callee.o目标文件中时,没有被改名。


4. 主调用C++代码源文件(caller.cpp)

8d390b6d1d97af7d7ecdc3f216a9c8.png


5. 编译主调用C++文件,得到可执行文件

f04ce1b88021b4b109bc2a698a39c4.png


知识点:

    g++在编译callee.h时,由于g++中定义了__cplusplus宏,因此它在调用函数 c_hello时,就会按照C的方式去调用(也就是没有名字改写),所以就能顺利的在callee.o中查找到这个函数。


三、总结

1. 在C++代码的函数声明时,如果代码会被C程序调用,一定要加上 extern "C"。

2. 在C代码的函数声明时,如果代码会被C++程序调用,也要加上extern "C"。

3. 在用C++编程时,最好各模块统一使用相同的编译器,包括版本最好也相同。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表凡亿课堂立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。
相关阅读
进入分区查看更多精彩内容>
精彩评论

暂无评论