在项目开发过程中,我们底层代码经常用C来实现,而上层应用大都会用C++实现,这样我们就涉及到了C和C++相互调用的情况了。那么,C/C++如何实现相互调用呢?
1、为什么会有差异?
1)编译方式不同:C文件常采用gcc编译,而Cpp文件常采用g++来编译2)C++支持函数重载:由于这一特性,C++和C中的同一个函数,经过编译后,生成的函数名称是不同的。
这样就导致了C与C++之间不能直接进行调用,要解决这一问题,就得靠extern "C"来辅助了。2、extern "C"
·externextern关键字我们并不陌生,它是编程语言中的一种属性,用来表示变量,函数等类型的作用范围。
我们经常在·"C"编程语言种类繁多,不同语言有不同的编译规则,如果想要互相调用,必须告诉编译器以什么规则去编译文件,这样才能正常调用。其主要作用是:把.c源文件中定义变量或者实现函数,在.h头文件中使用extern关键字进行声明,方便其他文件调用。
“C”当作一个标志位,告诉编译器,下面代码以C的方式编译!了解其中原理后,我们来实操一下!
3、C++调用C
我们创建3个文件,分别为main.cpp、cal.c、cal.h。

gcc和g++单独编译文件,编译出cal.o和main.o两个中间文件,很简单,定义了一个embedded_art的函数。# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [1532] $ ls cal.c cal.h main.cpp # dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [1543] $ gcc -c cal.c # dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [1549] $ g++ -c main.cpp # dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [1555] $ ls cal.c cal.h cal.o main.cpp main.o下面看一下编译之后的中间文件cal.o和main.o的符号表,看看同一个函数embedded_art不同编译方式之后的差别。

g++编译之后,对函数名称进行了加工,按照自身的编译规则,最终生成了一个新的函数名,所以我们如果直接调用cal.c中的embedded_art肯定是不行的。正确方式
使用extern "C"来使g++编译器用C的方式编译。在main.cpp文件中,我们引入cal.h的位置,添加extern "C"extern "C" { #include "cal.h" }再次进行编译,即可!

# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [1636] $ g++ main.o cal.o # dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [1654] $ ls a.out cal.c cal.h cal.o main.cpp main.o # dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test on git:main x [1657] $ ./a.out main entry 嵌入式艺术4、C调用C++
我们创建3个文件,分别为main.c、cal.cpp、cal.h。

gcc和g++单独编译文件,编译出cal.o和main.o两个中间文件,很简单,同样定义了一个embedded_art的函数。# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [1645] $ g++ -c cal.cpp # dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [1652] $ gcc -c main.c # dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [1656] $ ls cal.cpp cal.h cal.o main.c main.o下面看一下编译之后的中间文件cal.o和main.o的符号表,看看同一个函数embedded_art不同编译方式之后的差别。

extern "C"来告诉编译器按C的方式编译。我们在cal.h的声明部分添加,然后重新编译!extern "C" { extern void embedded_art(void); }


extern "C",这是什么情况?在main.c文件中,引入了c++的头文件cal.h,因为"C"在C++编译的时候才能识别,C语言中并没有这个关键字。所以,我们需要在g++编译的时候去加入extern "C",而gcc编译的时候跳过,这个时候就要提到c++编译时候的特定宏__cplusplus了,相当于一个阀门了。我们修改cal.h文件:#ifdef __cplusplus extern "C" { #endif extern void embedded_art(void); #ifdef __cplusplus } #endif这样就确保了,c++编译embedded_art函数的时候,采用C语法编译,而gcc编译的时候,不作处理。再次链接,执行!# dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [1606] C:1 $ gcc -no-pie cal.o main.o -o main # dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [1646] $ ls cal.cpp cal.h cal.o main main.c main.o # dong @ ubuntu in ~/WorkSpace/Donge_Programs/Unix_Programming_Learning/c_c++_call_test/c_call_c++ on git:main x [1601] $ ./main main entry 嵌入式艺术5、总结
C/C++之间的相互调用,归根到底就是:不同的语言有不同的编译规则,要想实现通用,就必须告诉编译器,按照目标语言的规则进行编译!
审核编辑 :李倩
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
函数
+关注
关注
3文章
4406浏览量
66838 -
C++
+关注
关注
22文章
2122浏览量
76712 -
编译器
+关注
关注
1文章
1669浏览量
51082
发布评论请先 登录
相关推荐
热点推荐
C/C++条件编译
条件编译是一种在编译时根据条件选择性地包含或排除部分代码的处理方法。在 C/C++ 中,条件编译使用预处理指令 #ifdef、#endif、#else 和 #elif 来实现。常用的条件编译指令有
发表于 12-05 06:21
C++程序异常的处理机制
1、什么是异常处理?
有经验的朋友应该知道,在正常的C和C++编程过程中难免会碰到程序不按照原本设计运行的情况。
最常见的有除法分母为零,数组越界,内存分配失效、打开相应文件失败等等。
一个程序
发表于 12-02 07:12
C/C++代码静态测试工具Perforce QAC 2025.3的新特性
Perforce Validate 中 QAC 项目的相对/根路径的支持。C++ 分析也得到了增强,增加了用于检测 C++ 并发问题的新检查,并改进了实体名称和实
技能+1!如何在树莓派上使用C++控制GPIO?
在使用树莓派时,你会发现Python和Scratch是许多任务(包括GPIO编程)中最常用的编程语言。但你知道吗,你也可以使用C++进行GPIO编程,而且这样做还有不少好处。借助WiringPi
C++ 与 Python:树莓派上哪种语言更优?
Python是树莓派上的首选编程语言,我们的大部分教程都使用它。然而,C++在物联网项目中同样广受欢迎且功能强大。那么,在树莓派项目中选择哪种语言更合适呢?Python因其简洁性、丰富的库和资源而被
Perforce QAC产品简介:面向C/C++的静态代码分析工具(已通过SO 26262认证)
Perforce QAC专为C/C++开发者打造,支持多种编码规范、功能安全标准(ISO 26262)等,广泛用于汽车、医疗、嵌入式开发领域,可帮助快速识别关键缺陷、提升代码质量、实现合规交付。
主流的 MCU 开发语言为什么是 C 而不是 C++?
在单片机的地界儿里,C语言稳坐中军帐,C++想分杯羹?难喽。咱电子工程师天天跟那针尖大的内存空间较劲,C++那些花里胡哨的玩意儿,在这儿真玩不转。先说内存这道坎儿。您当stm32f4的256kRAM
源代码加密、源代码防泄漏c/c++与git服务器开发环境
源代码加密对于很多研发性单位来说是至关重要的,当然每家企业的业务需求不同所用的开发环境及开发语言也不尽相同,今天主要来讲一下c++及git开发环境的源代码防泄密保护方案。企业源代码泄密场景一、在很多
基于OpenHarmony标准系统的C++公共基础类库案例:ThreadPoll
1、程序简介该程序是基于OpenHarmony标准系统的C++公共基础类库的线程池处理:ThreadPoll。本案例完成如下工作:创建1个线程池,设置该线程池内部有1024个线程空间。启动5个线程
Spire.XLS for C++组件说明
Spire.XLS for C++ 是一款专业的 C++ Excel 组件,可以用在各种 C++ 框架和应用程序中。Spire.XLS for C++ 提供了一个对象模型 Excel
AKI跨语言调用库神助攻C/C++代码迁移至HarmonyOS NEXT
/C++代码快速迁移至HarmonyOS NEXT。凭借卓越的兼容性,AKI已成为厂商与开发者打造鸿蒙原生应用过程中广泛使用的跨语言调用解决方案。
AKI是一款专为鸿蒙原生开发设计的FFI(外部函数接口
发表于 01-02 17:08
HighTec C/C++编译器套件全面支持芯来RISC-V IP
德国萨尔布吕肯,2024年12月5日——世界领先的汽车C/C++编译器解决方案提供商HighTec EDV Systeme GmbH宣布全面支持芯来科技的RISC-V IP。HighTec编译器

C与C++如何互相调用
评论