从编译角度看c和c++混合编译

news2025/6/18 13:43:44

往期地址:

  • 操作系统系列一 —— 操作系统概述
  • 操作系统系列二 —— 进程
  • 操作系统系列三 —— 编译与链接关系
  • 操作系统系列四 —— 栈与函数调用关系
  • 操作系统系列五——目标文件详解
  • 操作系统系列六 —— 详细解释【静态链接】

本期主题:
c和c++混合编译


C和C++混合编译

  • 1.回顾编译和链接
  • 2.简单例子使用gcc和ld
    • 1.gcc
    • 2.ld存在的问题(//TODO)
  • 3.c和c++混合编译
    • 1.使用nm看符号
    • 2.如何混合编译,extern "C"


1.回顾编译和链接

参考前面文章的链接,编译与链接 ,我们知道构建一共有4步:

  1. 预编译
  2. 编译
  3. 汇编
  4. 链接

我们常说的编译和链接,实际上编译包括了前面三步,即 预编译、编译和汇编

2.简单例子使用gcc和ld

写一个简单的例子,就是两个文件都是c文件,一个定义了func函数,另外一个main函数去调用func函数;

//func.h
#ifndef __FUNC_H__
#define __FUNC_H__
#include <stdio.h>
void func();
#endif

//func.c
#include "func.h"
void func(void)
{
	printf("C code, hello world!\n");
}

//main_c.c
#include "func.h"

int main(void)
{
	printf("main func\n");
	func();
	return 0;
}

1.gcc

使用gcc来编译和链接,makefile文件如下:

c_comp:
	gcc -c func.c
	gcc -c main_c.c
	gcc -o a.out func.o main_c.o
clean:
	rm *.o a.out
  1. gcc -c 是将xx.c文件生成目标文件,所谓目标文件的定义参考 操作系统系列五——目标文件详解
  2. gcc -o 是将目标文件链接成可执行文件

2.ld存在的问题(//TODO)

前面的例子如果用ld来进行链接,会存在问题:
在这里插入图片描述
问题是提示缺少了 puts 的reference信息,原因:

这是由于我们的函数用到了printf,printf的底层就是puts,printf依赖于libc.so,但是我们用ld链接时并未将libc.so链接进去

3.c和c++混合编译

将上面的例子改为cpp程序来调用c写好的接口:

//func.h
#ifndef __FUNC_H__
#define __FUNC_H__
#include <stdio.h>
void func();
#endif

//func.c
#include "func.h"
void func(void)
{
	printf("C code, hello world!\n");
}

//main.cpp
#include "func.h"

int main(void)
{
	printf("main func\n");
	func();
	return 0;
}

makefile如下:

cpp_comp:
	gcc -c func.c
	g++ -c main.cpp
	g++ -o a.out func.o main.o

编译结果:
在这里插入图片描述
提示找不到func函数,这是为什么呢?

1.使用nm看符号

我们来定位上面的问题,我们将编译生成的目标文件进行符号解析看看,我们使用nm命令,nm命令能够将目标文件中的symbols(即符号信息)都展示出来
nm命令:
在这里插入图片描述看 main.o 以及 func.o的符号信息:
在这里插入图片描述一看就发现了问题, main.o中对func的符号要求和func.o中的符号要求不一致,所以导致找不到func符号信息

原因剖析:

对于cpp代码而言,函数有重载的可能性,所以cpp编译的目标文件中,对于函数符号是会有参数信息的,例如 funcv实际上就是func(void)的意思
这也就意味着,使用 C 和 C++ 进行混合编程时,考虑到对函数名的处理方式不同,势必会造成编译器在程序链接阶段无法找到函数具体的实现,导致链接失败。

2.如何混合编译,extern “C”

c++已经考虑到了这个问题,所以提供了一个 extern “C” 的方案,作用是:

extern “C” 既可以修饰一句 C++ 代码,也可以修饰一段 C++ 代码,它的功能是让编译器以处理 C 语言代码的方式来处理修饰的 C++ 代码

前面我们那个例子,

  • 在main.cpp中包含了func.h头文件,main.cpp会以c++的方式来解析func函数
  • 而func.c中又是以c的方式来解析func函数

因此解决方案就是在func.h文件中添加extern C,告诉main.cpp同样以c的方式来解析func函数

#ifndef __FUNC_H__
#define __FUNC_H__
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif
	void func();
#ifdef __cplusplus
}
#endif

#endif

再次编译测试,能够正常匹配了:
在这里插入图片描述

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

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

相关文章

【蓝桥杯】计算指定日期为当年第几天

文章目录前言题目分析算法难度实战1、创建算法2、创建测试用例3、测试结果总结前言 蓝桥杯全国软件和信息技术专业人才大赛由工业和信息化部人才交流中心主办,每年参赛人数超过30000人。蓝桥杯大赛作为国内领先的全国性 IT 学习赛事&#xff0c;持续有力支撑综合测评、奖学金评…

Web前端开发:HTML、CSS

一. 前端开发介绍 在介绍Web网站工作流程的时候提到&#xff0c;前端开发&#xff0c;主要的职责就是将数据以好看的样式呈现出来&#xff0c;说白了&#xff0c;就是开发网页程序&#xff0c;如下图所示&#xff1a;1. 网页有哪些部分组成 ? 文字、图片、音频、视频、超链接…

车企跨界背后,智能手机进入新增长时代

2022年中国智能手机销量首次跌破了3亿部大关&#xff0c;创下了十年来的最低水平。与此同时&#xff0c;以新能源车和XR为代表的新形态终端日渐成为新宠。在行业内外部多重因素影响之下&#xff0c;“唱衰”智能手机的声音也在甚嚣尘上&#xff0c;甚至有不少人认为智能机已进入…

笔记本电脑开不了机?3种解决方法

案例&#xff1a;笔记本电脑开不了机怎么办&#xff1f; 【我的笔记本电脑一直用得好好的&#xff0c;今天突然开不了机&#xff0c;尝试按了开机键很多次也没有解决。有人遇到过同样的问题吗&#xff1f;有没有解决的方法&#xff01;】 在日常生活中&#xff0c;我们经常会…

Vulnhub靶场DC1-2练习

目录0x00 准备0x01 信息收集0x02 漏洞利用与攻击0x03 思路总结0x00 准备 下载连接&#xff1a;https://download.vulnhub.com/dc/DC-2.zip 介绍&#xff1a;Just like with DC-1, there are five flags including the final flag.Please note that you will need to set the …

看完这篇文章你就彻底懂啦{保姆级讲解}-----(I.MX6U驱动LED灯《使用汇编语言编写》) 2023.4.17

目录前言STM32 知识回顾完整汇编代码最终编译验证结束语前言 首先我们在开发stm32的时候驱动LED灯会有两种方式&#xff0c;分别是寄存器和库函数版本。因为在实际的开发过程中&#xff0c;我们更愿意更习惯用库函数版本来驱动各种外设&#xff0c;但是对于底层的寄存器调用和…

Linux宝塔安装msyql服务,默认密码,允许远程登录问题解决

一、首先我在宝塔安装mysql服务是5.7 1.1MySQL数据库5.6之前&#xff08;不包括&#xff09;默认密码为空&#xff0c;用户不用输入密码&#xff0c;直接回车登陆 mysql -uroot -p password:(空) 1.2.MySQL数据库5.6之后&#xff08;包括&#xff09;默认密码是MySQL数据库随机…

Mybatis手动配置ORM,不用自动ORM等操作

一、解决mapper.xml存放在resources以外路径中的读取问题 在pom.xml文件最后追加< build >标签&#xff0c;以便可以将xml文件复制到classes中&#xff0c;并在程序运行时正确读取。 <build><!-- 如果不添加此节点src/main/java目录下的所有配置文件都会被漏掉…

【Android Audio】TimeCheck机制

TimeCheck机制&#xff08;Android R/S&#xff09; TimeCheck.cpp TimeCheck.h frameworks/av/media/utils/TimeCheck.cpp TimeCheck守护线程的作用&#xff1a; 当audioserver中IAudioFlinger&#xff0c;IAudioPolicyService&#xff0c;IEffect中的每一个binder函数调用时…

Web 攻防之业务安全:Callback自定义测试(触发XSS漏洞)

Web 攻防之业务安全&#xff1a;Callback自定义测试 业务安全是指保护业务系统免受安全威胁的措施或手段。广义的业务安全应包括业务运行的软硬件平台&#xff08;操作系统、数据库&#xff0c;中间件等&#xff09;、业务系统自身&#xff08;软件或设备&#xff09;、业务所提…

学习C语言十天了,我实现了仿真自由落体小球『C/C++图形库EasyX』

文章目录&#x1f490;专栏导读文章导读准备工作一、显示一个静止的小球二、显示多个小球使用#define美化代码三、小球下落动画四、利用while循环实现小球下落五、利用if语句实现小球重复下落六、实现小球落地反弹七、实现小球加速下落&#x1f490;专栏导读 &#x1f338;作者…

剪枝与重参第七课:YOLOv8剪枝

目录YOLOv8剪枝前言1.Overview2.Pretrain(option)3.Constrained Training4.Prune4.1 检查BN层的bias4.2 设置阈值和剪枝率4.3 最小剪枝Conv单元的TopConv4.4 最小剪枝Conv单元的BottomConv4.5 Seq剪枝4.6 Detect-FPN剪枝4.7 完整示例代码5.YOLOv8剪枝总结总结YOLOv8剪枝 前言 …

【三十天精通Vue 3】第八天 Vue 3 生命周期钩子详解

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: 三十天精通 Vue 3 文章目录引言一、Vue 3 生命周期钩子概述1.1 生命周期钩子的简介1.2 生命周…

mulesoft MCIA 破釜沉舟备考 2023.04.14.11

mulesoft MCIA 破釜沉舟备考 2023.04.14.111. To implement predictive maintenance on its machinery equipment, ACME Tractors has installed thousands of IoT sensors that will send data for each machinery asset as sequences of JMS messages, in near real-time, to…

惠普Probook455电脑开机突然卡住无法进入桌面

惠普Probook455电脑开机突然卡住无法进入桌面解决方法分享。最近有用户使用的惠普Probook455电脑在开机的时候&#xff0c;电脑一直卡在开机的界面上&#xff0c;无法进入到系统中。无论是重启还是安全模式都无法解决问题。那么遇到这个情况怎么去进行问题的解决&#xff0c;来…

C++---状态压缩dp---炮兵阵地(每日一道算法2023.4.16)

注意事项&#xff1a; 本题为"状态压缩dp—蒙德里安的梦想"和"状态压缩dp—小国王"和"状态压缩dp—玉米田"的近似题&#xff0c;建议先阅读这三篇文章并理解。 题目&#xff1a; 司令部的将军们打算在 NM 的网格地图上部署他们的炮兵部队。 一个…

GoogleTest+VS code编译和编写简单测试用例

目录前言一、安装gtest二、 编译gtest与运行单元测试第一种编译方式第二种编译方式前言 在B站看了非常多Gtest的教学视频&#xff0c;CSDN上gtest博客也特别多&#xff0c;但是都非常陈旧或者根本不是用vscode。本篇目的在于&#xff0c;说明如何在vscode上编写简单单元测试。…

day01_Java概述丶环境搭建

Java背景知识 Java概述 概述&#xff1a;计算机语言就是人与计算机之间进行信息交流沟通的一种特殊语言。所谓计算机编程语言&#xff0c;就是人们可以使用编程语言对计算机下达命令&#xff0c;让计算机完成人们需要的功能。 Java语言&#xff1a;是美国Sun公司&#xff08…

Siamese network

文章目录一、相似性度量1. 欧氏距离2. 马氏距离二、Siamese network1. Siamese network 基础架构2. 损失函数3. 不同的Siamese network3.1. 行人重识别3.2 其他应用场景一、相似性度量 相似性度量是机器学习中一个非常基础的概念&#xff0c;是评定两个事物之间相似程度的一种度…

E: 仓库 “http://mirrors.aliyun.com/ubuntu eoan Release” 没有 Release 文件 —— 解决方案

Ubuntu 20.04 更新的时候&#xff0c;遇到如下问题&#xff1a; 可以通过修改源&#xff0c;来进行修复&#xff1a; 1、登录如下网址&#xff1a;LUGs repo file generator 2、选择对应的 Ubuntu 版本&#xff0c;这里我是 Ubuntu 20.04 点击 Download&#xff0c;会下载一个 …