C与C++相互调用

article/2025/8/6 7:34:40

CC++为什么相互调用的方式不同

C C++ 之间的相互调用方式存在区别,主要是由于 C C++ 语言本身的设计和特性不同。
函数调用和参数传递方式不同 C C++ 在函数调用和参数传递方面有一些不同之处。 C 使用标准 的函数调用约定,而 C++ 在函数调用中可能包含额外的信息,如函数重载和默认参数。为了正确匹配函数签名,C++ 编译器可能会在函数名上进行名称修饰( name mangling )。
函数重载和名称修饰 C++ 支持函数重载,即可以有相同的函数名但不同的参数列表。为了在可执行文件中区分这些重载函数,C++ 编译器会在函数名中添加一些信息,以便于重载解析。这与 C 的函数名约定不同,C 中函数名是平铺的。
链接库的差异 C C++ 编译器链接不同的标准库。 C 编译器链接 C 标准库,而 C++ 编译器链接 C++ 标准库。由于标准库可能涉及不同的函数和数据结构,因此在链接阶段可能会有不同的处理。
编译器特性 C C++ 编译器对代码的解析、优化、链接等可能会有不同的处理方式,这可能会导致在 C C++ 相互调用时需要进行适当的处理。
解决手段 :为了在 C C++ 之间实现相互调用, ==C++ 引入了 extern "C" 语法 == ,它可以用来告诉 C++ 编译器在函数声明上 使用 C 的调用约定 ,以便在链接阶段能够正确解析函数名。这种设计是为了在 C C++ 之间实现互操作性,但由于两者的语法和特性存在差异,因此在调用方式、编译器行为和链接方式上会存在一些差异。

C++中调用C

话不多说,直接上案例,下面是一个简单的示例,演示了如何在 C++ 代码中调用 C 函数:
首先分别创建三个文件: mylib.c mylib.h main.cpp
mylib.c 如下:
// mylib.c
#include <stdio.h>
void my_c_function () {
printf ( "This is a C function.\n" );
}
mylib.h 如下:
// mylib.h
#ifndef MYLIB_H
#define MYLIB_H
void my_c_function ();
#endif // MYLIB_H
main.cpp 如下:
// main.cpp
#include <iostream>
在这个示例中,我们使用了 #include "mylib.h" 来引入头文件,并在 C++ 中调用了
my_c_function() 。这样就能正确地在 C++ 中调用 C 函数。编译步骤如下:
gcc -c mylib.c -o mylib.o # 编译 C 文件为目标文件
g ++ -c main.cpp -o main.o # 编译 C++ 文件为目标文件
g ++ main.o mylib.o -o app # 链接目标文件生成可执行文件
编译后的文件列表如下:
然后运行可执行文件: ./app 得到输出结果:
这里可以使用 objdump 命令查看编译之后的中间文件 mylib.o main.o 的符号表:
可以发现, my_c_function() 函数编译出的名称在 mylib.o main.o 是相同。这是由于 ==C++
文件中使用 extern "C" 来声明 C 调用约定,以便 C 能够正确解析函数名。 ==
我们来看看如果没有使用 extern "C" 后的编译情况吧:
可以发现,不使用 extern "C" , 函数 my_c_function 编译后名称变为了 (_Z13my_c_functionv
是由于在 C++ 中, == 函数名在编译后会根据函数的参数类型和返回类型进行名称重整 == Name
Mangling ),以支持函数重载等特性。这是因为 ==C++ 支持函数的参数类型和个数可以不同,所以需要 在编译后为每个函数生成一个唯一的名称。==
当你在 C++ 中调用一个 C 函数时,如果不使用 extern "C" 声明, C++ 编译器会默认对函数名进行名 称重整。而在C 语言中,函数名不会被重整。
如果你 == C++ 中调用了一个 C 函数 == ,并且没有使用 extern "C" 声明, C++ 编译器会对函数名进 行名称重整,生成一个新的名字,类似 _Z13my_c_functionv 这样的名称。这个过程被称为名称重整 (Name Mangling ),是为了确保函数在 C++ 中能够正确处理函数重载等特性。

C中调用C++

下面还是来看一个简单的示例,演示了如何在 C 代码中调用 C++ 函数:
首先分别创建三个文件: mylib.cpp mylib.h main.c
mylib.cpp 如下:
// mylib.cpp
#include <iostream>
#include "mylib.h"
void my_cpp_function ( int num ) {
std::cout << "C++ function called with number: " << num << std::endl ;
}
mylib.h 如下:
// mylib.h
#ifndef MYLIB_H
#define MYLIB_H
#ifdef __cplusplus
extern "C" {
#endif
void my_cpp_function ( int num );
#ifdef __cplusplus
}
#endif
#endif // MYLIB_H
#endif // MYLIB_H
main.c 如下:
// c_main.c
#include <stdio.h>
#include "mylib.h"
int main () {
printf ( "Calling C++ function from C\n" );
// Call the C++ function
my_cpp_function ( 42 );
return 0 ;
在这个示例中,我们使用了 #include "mylib.h" 来引入头文件,并在 main.c 中调用了
my_cpp_function() 。这样就能正确地在 C 中调用 C++ 函数。编译步骤如下:
g ++ -c mylib.cpp -o mylib.o # 编译 C 文件为目标文件
gcc -o main main.c mylib.o -lstdc ++ # 链接目标文件生成可执行文件
注释 -lstdc++ 是用于链接 C++ 标准库的编译选项。在 Linux 系统中, C++ 标准库通常被命名为
libstdc++.so ,使用 -lstdc++ 编译选项可以将这个库链接到可执行文件中,以便在运行时使用
C++ 的标准库函数和功能。
如果缺少 -lstdc++ 则会报错:
编译后的文件列表如下:
然后运行可执行文件: ./main 得到输出结果:
这里解释一下 mylib.h 头文件中的 #ifdef __cplusplus :在 main.c 文件夹中调用 mylib.h 头文
件,但是 C 语言中并没有 extern 这个关键字,因此,使用 #ifdef __cplusplus 来充当一个译时候的 阀门。
总结一下 :对于 C 调用 C++ 的情况,没有 extern "C" 这样的关键字。您需要在 C++ 代码中使用
extern "C" 来确保 C++ 函数按照 C 的方式进行链接,同时在 C 代码中包含相应的头文件并调用这些函数

http://www.hkcw.cn/article/JAbBWCvfDx.shtml

相关文章

Nest全栈到失业(附加):Mysql+TypeOrm构建CRUD

前置内容 在此之前,我希望你准备好一个docker环境,以及魔法的网络哦 自己创建一个项目哈,使用nest new XXX Docker 什么是docker?相信很多人都知道了,说白了,就是一个镜像容器;以mysql为例,你在电脑上使用mysql5.6啥的,他电脑上是5.7啥的,然后数据内容不兼容了,怎么办了?他卸…

InnoDB引擎逻辑存储结构及架构

简化理解版 想象 InnoDB 是一个高效运转的仓库&#xff1a; 核心内存区 (大脑 & 高速缓存 - 干活超快的地方) 缓冲池 Buffer Pool (最最核心&#xff01;)&#xff1a; 作用&#xff1a; 相当于仓库的“高频货架”。把最常用的数据&#xff08;表数据、索引&#xff09;从…

基于定制开发开源AI智能名片S2B2C商城小程序的大零售渗透策略研究

摘要&#xff1a;本文聚焦“一切皆零售”理念下的大零售渗透趋势&#xff0c;提出以定制开发开源AI智能名片S2B2C商城小程序为核心工具的渗透策略。通过分析该小程序在需求感应、场景融合、数据驱动等方面的技术优势&#xff0c;结合零售渗透率提升的关键路径&#xff0c;揭示其…

基于SpringBoot的在线拍卖系统计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…

二分法算法技巧-思维提升

背景&#xff1a; 在写力扣题目“搜素插入位置 ”时&#xff0c;发现二分法的一个细节点&#xff0c;打算记录下来&#xff0c;先看一张图&#xff1a; 我们知道&#xff0c;排序数组&#xff0c;更高效的是二分查找法~~~而二分法就是切割中间&#xff0c;定义left是最开始的&…

实验分享|基于sCMOS相机科学成像技术的耐高温航空涂层材料损伤检测实验

1实验背景 航空发动机外壳的耐高温涂层材料在长期高温、高压工况下易产生微小损伤与裂纹&#xff0c;可能导致严重安全隐患。传统光学检测手段受限于分辨率与灵敏度&#xff0c;难以捕捉微米级缺陷&#xff0c;且检测效率低下。 某高校航空材料实验室&#xff0c;采用科学相机…

特伦斯 S75 电钢琴:重构演奏美学的极致表达

在数字音乐时代&#xff0c;电钢琴正从功能性乐器升级为融合艺术、科技与生活的美学载体。特伦斯 S75 电钢琴以极简主义哲学重构产品设计&#xff0c;将专业级演奏体验与现代家居美学深度融合&#xff0c;为音乐爱好者打造跨越技术边界的沉浸式艺术空间。 一、极简主义的视觉叙…

室内VR全景助力房产营销及装修

在当今的地产行业&#xff0c;VR全景已成为不可或缺的应用工具。从地产直播到楼市VR地图&#xff0c;从效果图到水电家装施工记录&#xff0c;整个地产行业的上下游生态中&#xff0c;云VR全景的身影无处不在。本文将探讨VR全景在房产营销及装修领域的应用&#xff0c;并介绍众…

AWS API Gateway 配置WAF(中国区)

问题 需要给AWS API Gateway配置WAF。 AWS WAF设置 打开AWS WAF首页&#xff0c;开始创建和配置WAF&#xff0c;如下图&#xff1a; 设置web acl名称&#xff0c;然后开始添加aws相关资源&#xff0c;如下图&#xff1a; 选择资源类型&#xff0c;但是&#xff0c;我这里出…

文件雕刻——一种碎片文件的恢复方法

文件雕刻是指基于对文件格式而非其他元数据的了解&#xff0c;在数据流中搜索文件的一种过程。 当文件系统元数据损坏或无法使用时&#xff0c;雕刻非常有用。FAT 文件系统&#xff08;通常用于小型介质&#xff09;是最常见的例子。 删除文件或格式化介质后&#xff0c;文件系…

如何解决MySQL Workbench中的错误Error Code: 1175

错误描述&#xff1a; 在MySQL Workbench8.0中练习SQL语句时&#xff0c;执行一条update语句&#xff0c;总是提示如下错误&#xff1a; Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY columnTo disab…

VScode-使用技巧-持续更新

一、Visual Studio Code - MACOS版本 复制当前行 shiftoption方向键⬇️ 同时复制多行 shiftoption 批量替换换行 在查找和替换面板中&#xff0c;你会看到一个 .∗ 图标&#xff08;表示启用正则表达式&#xff09;。确保这个选项被选中&#xff0c;因为我们需要使用正则…

【Redis】hash

Hash 哈希 几乎所有的主流编程语言都提供了哈希&#xff08;hash&#xff09;类型&#xff0c;它们的叫法可能是哈希、字典、关联数组、映射等。在 Redis 中&#xff0c;哈希类型指值本身又是一个键值对结构&#xff0c;形如 key “key”, value {{field1, value1}, …{field…

产品更新|数字主线深度解析:华望解决方案助力企业数字化转型

在数字化转型的浪潮中&#xff0c;企业如何打破数据孤岛、实现全流程协同是亟需解决的问题。数字主线&#xff08;Digital Thread&#xff09;作为新一代工业智能的核心技术&#xff0c;正在成为推动数字化转型的“加速引擎”。 一、什么是数字主线&#xff1f; 数字主线是贯穿…

PECVD 生成 SiO₂ 的反应方程式

在PECVD工艺中&#xff0c;沉积氧化硅薄膜以SiH₄基与TEOS基两种工艺路线为主。 IMD Oxide&#xff08;USG&#xff09; 这部分主要沉积未掺杂的SiO₂&#xff0c;也叫USG&#xff08;Undoped Silicate Glass&#xff09;&#xff0c;常用于IMD&#xff08;Inter-Metal Diele…

Centos7搭建zabbix6.0

此方法适用于zabbix6以上版本zabbix6.0前期环境准备&#xff1a;Lamp&#xff08;linux httpd mysql8.0 php&#xff09;mysql官网下载位置&#xff1a;https://dev.mysql.com/downloads/mysql/Zabbix源码包地址&#xff1a;https://www.zabbix.com/cn/download_sourcesZabbix6…

[CSS3]响应式布局

导读 响应式就是一套代码, 兼容大中小不同的屏幕, 即网页内容不变, 网页布局随屏幕切换而改变 媒体查询 响应式布局的核心技术是媒体查询 媒体查询可以检测屏幕尺寸, 设置差异化的css 开发中的常用写法 使用范围属性, 划定屏幕范围 max-width 最大宽度min-width 最小宽度 …

Postgre数据库分区生产实战

1.分区背景 随着业务的发展&#xff0c;单表数据量日益增加&#xff0c;服务端对数据查询时长逐步的在增大&#xff0c;单表已经不能满足正常的查询需求了。所以&#xff0c;对于Postgre数据库最好的办法就是针对这个一个数据量比较大的表&#xff0c;对其进行分区处理。为啥采…

高效微调大模型:LoRA技术详解

LoRA&#xff08;Low-Rank Adaptation&#xff09;是一种用于微调大型预训练模型的技术&#xff0c;旨在高效地适应特定任务&#xff0c;同时减少计算和存储开销。 预训练模型&#xff1a;如DeepSeek、BERT、GPT等&#xff0c;已在大量数据上训练&#xff0c;具备广泛的语言理…

大规模JSON反序列化性能优化实战:Jackson vs FastJSON深度对比与定制化改造

背景&#xff1a;500KB JSON处理的性能挑战 在当今互联网复杂业务场景中&#xff0c;处理500KB以上的JSON数据已成为常态。 常规反序列化方案在CPU占用&#xff08;超30%&#xff09;和内存峰值&#xff08;超原始数据3-5倍&#xff09;方面表现堪忧。 本文通过Jackson与Fas…