C与C 混合编程

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

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

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

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

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

知识点:

(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中的符号:

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

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

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

知识点:

(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)

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

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

知识点:

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

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

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

知识点:

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

三、总结

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

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

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

不知道这篇博文对你有没有帮助呢?

(0)

相关推荐

  • extern “C”的作用详解

    extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码.加上extern "C"后,会指示编译器这部分代码按C语言(而不是C++)的方式 ...

  • C 如何调用写好的C接口?

    前言 如何在C++代码中调用写好的C接口?你可能会奇怪,C++不是兼容C吗?直接调用不就可以了,那么我们来测试一下,先看看C++如何调用C代码接口的. C++调用C文件 一个C语言文件test.c # ...

  • Windows驱动开发需要注意的细节

    Windows驱动开发需要注意的细节 此"Hello, World"示例与 C++ 程序一样简单. 现实世界中的程序通常有头文件.更多源文件和指向库的链接. 你可以使用本演练中的步 ...

  • aardio 批处理 混合编程

    aardio 新版提供了 process.batch 可以方便地嵌入批处理.process.batch  的源代码很少只有数十行,支持的功能如下: 1.实现隐藏控制台窗口执行批处理代码,轻松地为批处理 ...

  • 【青少年编程】【四级】加减法混合运算器

    「青少年编程竞赛交流群」已成立(适合6至18周岁的青少年),公众号后台回复[Scratch]或[Python],即可进入.如果加入了之前的社群不需要重复加入. 我们将有关编程题目的教学视频已经发布到抖 ...

  • “病毒-人类”混合DNA?新研究称新冠病毒可整合到人类基因组中

    ▎药明康德内容团队编辑 为什么一些新冠病毒感染者在痊愈几个月之后,检测依旧显示阳性?几名科学家有一个看起来很疯狂的想法--新冠病毒会把自己的遗传物质插入到人类的基因组里.今天,<美国国家科学院院 ...

  • 中国信通院洪坤贤:混合云形态持续演进,四大能力成为关键

    中国信息通信研究院(以下简称"中国信通院")发布的<云计算发展白皮书(2020年)>显示,经历十余年发展,中国云计算市场规模已经从最初的十几亿元快速成长至2020年的近 ...

  • 分布式混合学习模型

    通讯技术的发展促进了地理上分散的团队的文化,这些团队包括在客户位置工作的员工,在家工作的员工和远程工作的员工.对于销售团队而言,必须在偏远地区分配员工. 随着时间的推移,管理分布式劳动力的挑战和风险越 ...

  • 这摩托车无怠速,火花塞漆黑,却不是混合气过浓导致的……

    最近维修一台仿CG125顶杆机,无怠速,常规手法先看火花塞,拆下一看火花塞是粉黑粉黑的,有经验的师傅肯定会说混合气过浓!确实如此吗?且看我逐步排查. 再拆空滤发现是新的,排队了过脏堵塞问题 再拆化油器 ...

  • 11个用于编程和开发的最佳Linux发行版[2021版]

    基于Linux的操作系统是最受欢迎的,并且最适合开发人员和程序员.大多数开发人员使用不同的Linux发行版来迅速完成工作并创建新的东西,但是作为我自己的前开发人员,我主要担心的一个问题是"我 ...

  • 踏板摩托车冒黑烟,却不是混合气过浓,你听说过车上“迷宫”吗?

    作者:摩托中国 爱摩托 现代踏板摩托车除了水冷车型采用立式发动机外,一般都装用卧式发动机(如:市场上常见的GY6机型),气缸盖与曲轴箱基本处于平行状态. 发动机在工作过程中,曲轴连杆和活塞.活塞环分别 ...

  • 摩托车这个现象是混合气过浓吗?怎么做进一步判断?

    判断可燃混合气过浓的方法很简单,就是将故障摩托车停车,待发动机冷却10分钟左右,再从汽缸盖上拆下火花塞,仔细观察火花塞电极的颜色,正常颜色为棕红色,如颜色发黑,即可判断该摩托车存在可燃混合气过浓现象. ...