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

总结

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

echarts隔行背景色

看了下使用说明&#xff0c;试了半天终于搞对了 参考文档&#xff1a;Documentation - Apache ECharts option {xAxis: {type: category,data: [Mon, Tue, Wed, Thu, Fri, Sat, Sun]},yAxis: {type: value},series: [{data: [120, 200, 150, 80, 70, 110, 130],type: bar,mar…

【实用软件】Internet Download Manager(IDM6.41)下载及安装教程

​数据表明但是能够通过搭配下载的方式来使用IDM&#xff08;比如用迅雷离线下载&#xff0c;115离线&#xff0c;百度网盘等离线下载好的资源&#xff0c;然后结合HTTP协议的特性再用IDM下载&#xff09;能够达到事半功倍的效果。有目共睹的是IDM下载HTTP链接十分快&#xff0…

华为升腾显卡选型备忘

目录 1. 开发套件 2. 加速模块 3. 加速卡 4. 训练卡 官方地址&#xff1a;https://www.hiascend.com/ 备注&#xff1a; &#xff08;1&#xff09;V后缀的都是Video视频解析卡&#xff0c;本质是推理卡&#xff1b; &#xff08;2&#xff09;I后缀的都是推理卡&#…

(python)小学出题热门词汇可视化绘制

1.代码 import pandas as pd from wordcloud import WordCloud import matplotlib.pyplot as plt from collections import Counter import jieba # 如果你处理的是中文文本&#xff0c;需要jieba分词 import re # 停用词列表&#xff0c;这里只是示例&#xff0c…

Swift 周报 第五十四期

文章目录 前言新闻和社区苹果上架 iPhone 14/Pro 官翻机&#xff1a;起售价不到 5000 元苹果 iPhone SE 4 售价曝光苹果针对欧盟 20 亿美元罚单提起上诉 双方另一场“缠斗”已跨越近八年 提案通过的提案正在审查的提案 Swift论坛推荐博文话题讨论关于我们 前言 本期是 Swift 编…

SAP ABAP 之OOALV

文章目录 前言一、案例介绍/笔者需求二、SE24 查看类 a.基本属性 Properties b.接口 Interfaces c.友元 Friends d.属性 Attributes e.方法 Methods f.事件 Events g.局部类型 Types …

Vulnhub--AI: WEB: 2

渗透复现 平台框架存在目录穿越漏洞&#xff0c;利用该漏洞读取敏感信息 Ping功能点绕过&#xff0c;进行命令执行操作&#xff0c;反弹shell无果后&#xff0c;利用目录穿越漏洞遍历敏感API&#xff0c;读取到用户SSH登录凭证 SSH登录进行Linux lxd容器提权 知识扩展 目录…

企业运维六边形战士 质量稳定 效率为王

随着信息化的不断深入和扩展&#xff0c;企业IT系统的复杂性和设备多样性日益增加。为了保障业务的高可用性和连续性&#xff0c;企业需要一个全面、高效、智能的一体化运维管理平台。在用户市场的推动下&#xff0c;LinkSLA智能运维管家展现出【六边形战士】的优质属性&#x…

最年轻的国家最高科技奖得主,量子领域科学家:薛其坤

6月24日&#xff0c;2023年度国家最高科学技术奖在京揭晓&#xff0c;李德仁院士、薛其坤院士获得中国科技界崇高荣誉。 薛其坤是凝聚态物理领域著名科学家&#xff0c;取得多项引领性的重要科学突破&#xff0c;包括&#xff1a;他率领团队首次实验观测到量子反常霍尔效应&am…

【c语言】二级指针

1&#xff0c;定义 本质还是从指针的角度去理解&#xff0c;只不过存的指针的值 2&#xff0c;使用方法

怎么在线一次压缩多张图片?分享3款简单的在线图片压缩工具

在日常工作和生活中&#xff0c;经常会需要使用图片处理大小功能&#xff0c;网上有很多的图片压缩工具都能够快速处理图片大小&#xff0c;那么当遇到大量的图片需要压缩大小时&#xff0c;该如何操作才能快速在线压缩图片大小呢&#xff1f;多张图片怎么一次批量压缩&#xf…

Python 全栈体系【四阶】(六十一)

第五章 深度学习 十三、自然语言处理&#xff08;NLP&#xff09; 5. NLP应用 5.2 文本情感分析 目标&#xff1a;利用训练数据集&#xff0c;对模型训练&#xff0c;从而实现对中文评论语句情感分析。情绪分为正面、负面两种 数据集&#xff1a;中文关于酒店的评论&#…

使用Servlet开发javaweb,请求常见错误详解及其解决办法【404、405、500】

Servlet报错的情况多种多样&#xff0c;涵盖了配置错误、代码逻辑错误、资源未找到、权限问题等多个方面。以下是一些常见的Servlet报错情况及其可能的原因和解决方法&#xff1a; 404 Not Found: 错误原因图示&#xff1a; URL映射 发送请求&#xff0c;出现404错误 原因: 请…

基于jeecgboot-vue3的Flowable流程-自定义业务表单处理(一)支持同一个业务多个关联流程的选择支持

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 这部分先讲讲支持自定义业务表单一个业务服务表单多个流程的支持处理 1、后端mapper部分 如下&#xff0c;修改selectSysCustomFormByServiceName为list对象&#xff0c;以便支持多个 &…

通信系统网络架构_1.局域网网络架构

当今&#xff0c;通信网络从大的方面主要包括局域网、广域网、移动通信网等网络形式。不同的网络会采用不同的技术进行网络构建。以下针对不同的网络给出各自的网络架构以及所采用的技术。 1.概述 局域网&#xff0c;即计算机局部区域网络&#xff0c;是一种为单一机构所拥有的…

Simufact Additive增材制造支撑创建功能

增材制造工艺作为近年来制造行业的顶流&#xff0c;一直备受各行业关注。除了率先大范围展开增材制造应用的航空行业&#xff0c;在汽车、电子乃至医疗行业也都有了不俗的进展。深谙增材制造工艺的学者都直言&#xff1a;使用3D打印简单&#xff0c;但应用好比较难。那是因为这…

【高校科研前沿】四川大学刘超研究员为一作在《Geophys. Res. Lett.》发表团队成果:植被形态影响河床泥沙输运

文章简介 论文名称&#xff1a;Plant morphology impacts bedload sediment transport 第一作者及单位&#xff1a;刘超&#xff08;研究员|四川大学水利水电学院&#xff09; 通讯作者及单位&#xff1a;Yuqi Shan&#xff08;四川大学灾后重建与管理研究所&#xff09; 文…

【HashMap和HashSetyi以及散列表的拉链法,线性探测法详解】

&#x1f308;个人主页&#xff1a;SKY-30 ⛅个人推荐&#xff1a;基于java提供的ArrayList实现的扑克牌游戏 |C贪吃蛇详解 ⚡学好数据结构&#xff0c;刷题刻不容缓&#xff1a;点击一起刷题 &#x1f319;心灵鸡汤&#xff1a;总有人要赢&#xff0c;为什么不能是我呢 &…

昇思25天学习打卡营第2天 | 张量Tensor

张量Tensor 张量&#xff08;Tensor&#xff09;基础 张量是MindSpore中的基本数据结构的一种&#xff0c;类似于NumPy中数组和矩阵非常相似。它具有以下重要属性&#xff1a; 形状&#xff08;shape&#xff09;和数据类型&#xff08;dtype&#xff09;&#xff1a;每个张量…

如何找到合适的Python第三方库?

找合适的Python库其实很简单&#xff0c;按照以下三步法&#xff0c;你能找到90%的Python库。 1、百度谷歌搜索 明确自己的需求&#xff0c;用Python来干什么&#xff0c;力求简短明了。比如定位“数据分析”&#xff0c;然后去搜索关键词【Python数据分析第三方库】&#xf…