C++:C与C++混合编程

混合编程

  • 为什么需要混合编程
    (1)C有很多优秀成熟项目和库,丢了可惜,重写没必要,C++程序里要调用
    (2)庞大项目划分后一部分适合用C,一部分适合用C++
    (3)其他情况,如项目组一部分人习惯用C,一部分习惯用C++

  • 为什么不同语言可以混合编程
    (1)程序编译过程:源文件->目标(库)文件->可执行程序->镜像文件
    (2)任何编程语言执行时都必须是可执行程序,所以都必须先被编译成目标文件
    (3)混合编程的“混合”操作发生在链接这一步

  • C++和C混合编程的困难所在
    (1)C++和C都是编译型语言,互相混合相对容易
    (2)难点:C++支持函数名重载,而C不支持,因此编译器生成目标文件时,函数名在目标文件中的临时内部名称规则不同。导致链接时符号对不上
    (3)解决方案:使用extern “C”{}; 让C++在对接的局部向C妥协兼容
    通用解决方案:在C的头文件中加extern "C"声明,在C++中直接包含头文件调用即可

  • 使用objdump工具来研究函数编译后的符号
    (1)写个典型的C语言库mylib.c和mylib.h,提供add和sub等几个函数
    (2)使用gcc -c -o编译得到库文件,再objdump -d反汇编得到.i文件
    (3)对比加不加extern "C"这2种情况下得到的.i文件的符号差异
    实验第1步:证明了C语言中名称为add的函数,编译后符号表中就叫add

gCC -c clib.c -o clib.o
objdump -d clib.o > clib.i
gCC -c clib.c -o clib2.o
objdump -d clib2.o > clib.i

在这里插入图片描述

实验第2步:证明了C++语言中名称为add的函数,编译后符号表中叫_Z3addii
分析:同样的源码,编译后生成的二进制代码其实是一样的,所以功能其实也是一样的
所以本质上是可以混合编程的,但是生成的中间符号名称不同,所以链接器难受
实验第3步:证明了在C++的头文件中,只要把C++的函数的声明放在extern “C”{}的大括号范围之内,就可以让g++在编译这个函数时生成中间符号名时按照C的规则而不是按照C++的规则,所以这样的函数就可以和C的库进行共同链接。


extern "C" {
void fun();
}

#if __cplusplus
extern "C" {
#endif

#if __cplusplus
}
#endif
  • #if __cplusplus: 这是一个预处理器指令,用于检查当前代码是否在 C++ 环境中编译。__cplusplus 是一个预定义的宏,它在编译 C++ 代码时被定义为一个年份值,比如 199711L 或更高。因此,#if __cplusplus 的作用是在编译时判断是否为 C++ 环境。

  • extern “C”: 这是 C++ 提供的一种语法,用于告诉编译器按照 C 的方式对待包裹在其中的代码。在 C++ 中,函数名会被编译器进行名称修饰(name mangling),以支持函数重载和命名空间等特性。而 C 中没有这些特性,函数名不会进行修饰。因此,当 C++ 调用 C 的函数时,需要使用 extern “C” 来告诉编译器按照 C 的方式来处理函数名,以便在链接时能够正确找到对应的函数。

  • #endif: 这是预处理器指令,表示条件编译的结束。与 #if 配对使用,用于结束条件编译的代码块

预编译

g++ -E main.cpp -o main.i

生产静态库

ar -r libclib.a clib.o
g++ main.cpp -lclib -L.

C调用C++库的方法

代码实战:C调用C++库中的函数

构建C++库

gcc cppadd.cpp -c -o cppadd.o
ar -r libcppadd.a cppadd.o

反编译查看信息

 objdump -d libcppadd.a > libcppadd.i

在这里插入图片描述
test.c

在这里插入代码片
extern int _Z3addii(int a,int b);

int main(void)
{
    _Z3addii(1,2);
    return 0;
}
gcc test.c -lcppadd -L.

解决方案:添加一层封装层

g++ cppaddwrapper.cpp -c -o cppaddwrapper.o -lcppadd -L.
ar -r libcppaddwrapper.a cppaddwrapper.o
objdump -d libcppaddwrapper.a > cppaddwrapper.i

在这里插入图片描述

 gcc test.c -lcppaddwrapper -lcppadd -L. 

因为一开始的add是这样编写的

int add(int a, int b) {
  cout << "a + b = " << a + b << endl;
  return 0;
}

#include "cppadd.hpp"的引入放在cppaddwrapper.cpp

还是会出现报错。提示有东西没有引入

/usr/bin/ld: ./libcppadd.a(cppadd.o): warning: relocation against _ZSt4cout' in read-only section .text’
/usr/bin/ld: ./libcppadd.a(cppadd.o): in function add(int, int)': cppadd.cpp:(.text+0x1f): undefined reference to std::cout’
/usr/bin/ld: cppadd.cpp:(.text+0x27): undefined reference to std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)' /usr/bin/ld: cppadd.cpp:(.text+0x3c): undefined reference to std::ostream::operator<<(int)’
/usr/bin/ld: cppadd.cpp:(.text+0x43): undefined reference to std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)' /usr/bin/ld: cppadd.cpp:(.text+0x4e): undefined reference to std::ostream::operator<<(std::ostream& (*)(std::ostream&))’
/usr/bin/ld: ./libcppadd.a(cppadd.o): in function __static_initialization_and_destruction_0(int, int)': cppadd.cpp:(.text+0x85): undefined reference to std::ios_base::Init::Init()’
/usr/bin/ld: cppadd.cpp:(.text+0xa0): undefined reference to `std::ios_base::Init::~Init()’
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status

#include "cppadd.hpp"的引入放在cppaddwrapper.cpp
还是会出现报错。提示有东西没有引入

/usr/bin/ld: ./libcppaddwrapper.a(cppaddwrapper.o): in function addwrapper': cppaddwrapper.cpp:(.text+0x1d): undefined reference to add’
collect2: error: ld returned 1 exit status

总结

理解混合编程的存在性,知道解决方法

学习记录,侵权联系删除。
来源:朱老师物联网大课堂

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/743619.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS角落里的知识:“开发应用沉浸式效果”

概述 典型应用全屏窗口UI元素包括状态栏、应用界面和底部导航条。开发应用沉浸式效果主要指通过调整状态栏、应用界面和导航条的显示效果来减少状态栏导航条等系统界面的突兀感&#xff0c;从而使用户获得最佳的UI体验。 图1 界面元素示意图 开发应用沉浸式效果主要要考虑如下…

心灵馆咨询系统小程序心理咨询平台聊天咨询

心灵馆咨询系统小程序&#xff1a;解锁你的心灵密码 &#x1f496; 心灵之旅的导航者 在繁忙的现代生活中&#xff0c;我们时常会面临各种压力与困惑。心灵馆咨询系统小程序&#xff0c;如同一位贴心的导航者&#xff0c;引领我们探索内心的世界&#xff0c;寻找真正的自我。 …

DDP(Differential Dynamic Programming)算法举例

DDP(Differential Dynamic Programming)算法 基本原理 DDP(Differential Dynamic Programming)是一种用于求解非线性最优控制问题的递归算法。它基于动态规划的思想,通过线性化系统的动力学方程和二次近似代价函数,递归地优化控制策略。DDP的核心在于利用局部二次近似来…

北大医院副院长李建平:用AI解决临床心肌缺血预测的难点、卡点和痛点

2024年6月14日&#xff0c;第六届北京智源大会在中关村展示中心开幕&#xff0c;海内外的专家学者围绕人工智能关键技术路径和应用场景&#xff0c;展开了精彩演讲与尖峰对话。在「智慧医疗和生物系统&#xff1a;影像、功能与仿真」论坛上&#xff0c;北京大学第一医院副院长、…

[经典]原型资源:蚂蚁金服UI模版部件库

部件库预览链接&#xff1a; https://d3ttsx.axshare.com 支持版本: Axrure RP 8 文件大小: 30MB 文档内容介绍 基本部件&#xff1a;表单样式&#xff1a;12款、数据样式&#xff1a;10款、服务样式&#xff1a;6款、导航&#xff1a;5款、业务组件&#xff1a;7款、 模板…

区块链技术与数字货币

1.起源 ➢中本聪(Satoshi Nakamoto), 2008 ➢比特币:一种点对点的电子现金系统 2.分布式账本技术原理 1.两个核心技术&#xff1a; ➢以链式区块组织账本数据实现账本数据的不可篡改 ➢分布式的可信记账机制 2.共识机制&#xff1a;由谁记账 ➢目的&#xff1a; ⚫ 解…

鸿蒙开发系统基础能力:【@ohos.hiTraceMeter (性能打点)】

性能打点 本模块提供了追踪进程轨迹&#xff0c;度量程序执行性能的打点能力。本模块打点的数据供hiTraceMeter工具分析使用。 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 impor…

AcWing算法基础课笔记——状态压缩DP:蒙德里安的梦想

状态压缩DP 状态是整数&#xff0c;但把它看成二进制数&#xff0c;二进制中每一位是0或1表示不同的情况。 蒙德里安的梦想 291. 蒙德里安的梦想 - AcWing题库 题目 求把 NM&#x1d441;&#x1d440; 的棋盘分割成若干个 1212 的长方形&#xff0c;有多少种方案。 例如…

Java面试题:聚簇索引和非聚簇索引

聚簇索引和非聚簇索引 聚簇索引(聚集索引) 将数据的存储和索引放在一块,索引结构的叶子节点保存了行数据 索引字段必须存在,且只能存在一个 非聚集索引(二级索引) 将数据和索引分开存储,索引结构的叶子节点关联的是对应的主键 索引字段可以存在多个 索引的选取规则 如果…

2024 年 8 款最佳建筑 3D 渲染软件

你现在使用的3D 渲染软件真得适合你吗&#xff1f; 在建筑和室内渲染当中&#xff0c;市面上有许多3D渲染软件可供选择。然而&#xff0c;并不是每款软件都适合你的需求。本指南将重点介绍2024年精选的8款最佳建筑3D渲染软件&#xff0c;帮助你了解不同的选项&#xff0c;并选…

第100+13步 ChatGPT学习:R实现决策树分类

基于R 4.2.2版本演示 一、写在前面 有不少大佬问做机器学习分类能不能用R语言&#xff0c;不想学Python咯。 答曰&#xff1a;可&#xff01;用GPT或者Kimi转一下就得了呗。 加上最近也没啥内容写了&#xff0c;就帮各位搬运一下吧。 二、R代码实现决策树分类 &#xff08;…

SSM宠物领养系统-计算机毕业设计源码08465

目 录 摘要 1 绪论 1.1课题背景及意义 1.2研究现状 1.3ssm框架介绍 1.3论文结构与章节安排 2 宠物领养系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 …

大模型管理平台:one-api使用指南

大模型相关目录 大模型&#xff0c;包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容 从0起步&#xff0c;扬帆起航。 大模型应用向开发路径&#xff1a;AI代理工作流大模型应用开发实用开源项目汇总大模…

Go 实现SFTP连接服务

我们将SFTP连接和处理逻辑&#xff0c;以及登录账户信息封装&#xff0c;这样可以在不同的地方重用代码&#xff0c;并且可以轻松地更改登录凭据。下面我将演示如何使用Go语言中的结构体来封装这些信息&#xff0c;并实现一个简单的SFTP服务器&#xff1a; package mainimport…

信息系统项目管理师 | 新一代信息技术

关注WX&#xff1a;CodingTechWork 物联网 定义 The Internet of Things是指通过信息传感设备&#xff0c;按约定的协议&#xff0c;将任何物品与互联网连接&#xff0c;进行信息交互和通信&#xff0c;以实现智能化识别。定位、跟踪、监控和管理的一种网络。物联网主要解决…

采购OLED透明屏指南

一、引言 OLED透明屏作为一种前沿的显示技术&#xff0c;以其独特的透明度和出色的显示效果&#xff0c;受到了众多行业的青睐。在采购OLED透明屏时&#xff0c;需要综合考虑多个因素&#xff0c;以确保选择到符合需求的高质量产品。以下是一份详细的采购OLED透明屏指南&#x…

昇思25天学习打卡营第1天|基本介绍与快速入门

先贴上打卡截图 基本介绍 首先来看基本介绍&#xff0c;昇思MindSpore是华为的一个全场景深度学习框架&#xff0c;属于昇腾AI全栈的一部分。 总体架构如下图所示&#xff08;来自官方学习材料&#xff09; 从对底层多样性硬件适用的Runtime到应用层面的Model Zoo、科学计算…

首码项目对接app推广,寻找核心资源项目!

深度挖掘首码网&#xff08;www.shoumw.com&#xff09;项编码项目网站&#xff1a;帮助您轻松获取最新项目资源 在当下这个充满机会和挑战的创业氛围中&#xff0c;找到可信赖的项目资源已成为创业者们的主要任务。首码项目网是一家专注于首码项目发布和推广的平台&#xff0c…

Hi3861 OpenHarmony嵌入式应用入门--LiteOS MessageQueue

CMSIS 2.0接口中的消息&#xff08;Message&#xff09;功能主要涉及到实时操作系统&#xff08;RTOS&#xff09;中的线程间通信。在CMSIS 2.0标准中&#xff0c;消息通常是通过消息队列&#xff08;MessageQueue&#xff09;来进行处理的&#xff0c;以实现不同线程之间的信息…

Calibre - 合并电子书(EpubMerge)

这里使用 Calibre 软件和 EpubMerge 插件 EpubMerge github &#xff1a; https://github.com/JimmXinu/EpubMerge 1、安装 Merge 插件 安装后需要重启 calibre 2、查看设置 4 3、选中文件、开始合并 合并完成后&#xff0c;会弹窗窗口&#xff0c;来编辑 合辑的元信息 完成…