03在ESP-IDF中使用C++面向对象编程

在ESP-IDF中使用C和C++进行混合编译

ESP-IDF是Espressif Systems开发的官方IoT开发框架,用于编程和开发ESP32系列的微控制器。虽然ESP-IDF主要使用C语言编写,但它也支持使用C++进行开发

为什么要进行混合编译?

C++是一种功能强大的编程语言,它提供了许多C语言不具备的特性,如类(对象导向编程)、异常处理、函数重载等。然而,C语言在嵌入式系统开发中仍然占据主导地位,因为它更接近硬件,运行效率高,且占用资源少。

因此,混合编译允许开发者在同一个项目中利用C++的高级特性和C的效率。例如,你可以在C++中编写面向对象的代码,用于处理复杂的逻辑和数据结构,同时在C中编写底层的硬件操作代码。

如何进行混合编译?

在ESP-IDF中进行混合编译主要涉及到两个方面:源文件的组织链接性的处理

源文件的组织

在ESP-IDF项目中,源文件通常按照组件(component)来组织。每个组件都有自己的目录,包含了该组件的源文件和头文件,以及一个CMakeLists.txt文件,用于告诉CMake如何编译这些源文件。

在一个混合编译的项目中,你可以有一些组件是用C编写的,一些组件是用C++编写的。例如,你可以有一个用C编写的LED组件,用于控制LED的亮度和颜色,同时有一个用C++编写的KEY组件,用于初始化和扫描按键键值。

用一个按键控制LED的项目举例,下面是这个项目的文件构成

在这里插入图片描述
main.cppLED.cLED.hKEY.cppKEY.h是我们项目中需要编译链接的文件,它们和CMakeLists.txt的文件结构如下

  • 02KEY
    • components
      • LED
        • LED.c
        • LED.h
      • KEY
        • KEY.cpp
        • KEY.h
    • CMakeLists.txt
  • main
    • main.cpp
    • CMakeLists.txt

components组件下的.cpp/,c和.h

components文件下的CMakeLists.txt指定了该组件的源文件、头文件目录和依赖项。将 LED/LED.cKEY/KEY.cpp文件作为源文件,LEDKEY目录作为头文件目录,并将 driver 组件作为依赖项(driver组件是在项目中用到的,所以要将它加入到依赖项)。

idf_component_register(SRCS "LED/LED.c" "KEY/KEY.cpp"INCLUDE_DIRS "LED" "KEY"REQUIRES driver
)

main文件下的main.c

第一步
将main文件夹下的main.c重命名为main.cpp

第二步
main文件下的CMakeLists.txt同样只需要将main.c改为main.cpp即可

项目创建自动生成的:

idf_component_register(SRCS "main.c"INCLUDE_DIRS ".")

修改之后的

idf_component_register(SRCS "main.cpp"INCLUDE_DIRS ".")

链接性的处理

当C和C++代码在同一个项目中混合使用时,一个重要的问题是链接性(linkage)。链接性决定了一个符号(如函数或变量)在链接时如何被处理。C++支持函数重载,因此在编译后,C++函数的名字会被修饰(mangled)以表示它们的参数类型。然而,C语言没有这个特性,因此C函数的名字在编译后保持不变。

为了解决这个问题,C++提供了extern "C"这个关键字,用于声明一个符号使用C链接。当C++编译器看到extern "C"时,它会知道后面的代码应该按照C的规则来处理,因此不会对函数名进行修饰。

在ESP-IDF中,如果你有一个C++组件需要调用C组件的函数,你可以在C++代码中这样声明C函数:

extern "C" void led_set(int date);

同样,如果你有一个C组件需要调用C++组件的函数,需要在C代码中声明C++函数:

extern void led_read(void);

注意,C代码中不需要使用extern "C",因为C编译器不支持这个关键字。

下面我们继续拿刚刚按键控制LED的项目举例

以下是main.cppLED.cLED.hKEY.cppKEY.h文件的处理方式:

  • main.cpp:在这个文件中,我们了包含LED.hKEY.h。而void app_main(void)是ESP-IDF为我们提供的主程序,我们需要使用extern "C"来声明这个主程序

    #include "LED.h"
    #include "KEY.h"extern "C" void app_main(void){
    //程序实现-----
    }
    
  • LED.c和LED.h:这两个文件应该是C语言编写的,所以我们不需要做任何特殊的处理。

  • KEY.cpp和KEY.h:这两个文件是C++编写的。在KEY.h中,我们使用extern "C"来包含类定义的所有内容。在KEY.cpp中,需要使用extern "C"来定义这些成员函数

    KEY.h

    // KEY.h
    #ifdef __cplusplus
    extern "C" {
    #endifclass Key {
    public// 构造函数Key(gpio_num_t pin);
    }#ifdef __cplusplus
    }
    #endif
    

    KEY.cpp

    // KEY.cpp#include "KEY.h"extern "C" Key::Key(gpio_num_t pin): pin(pin) {// ...}
    

注意 注意 类的成员函数不要使用inline(内联)要不然.h和.cpp文件可能会无法链接到,我就踩了这个坑😭😭一直以为是CMake写的不对,所以链接不上捣鼓了一天,最后都准备要把ESP-IDF给卸载重装了,在卸载前我还是不信邪,我把程序发给ChatGPT问它有什么问题,好家伙ChatGPT直接点出了问题所在,类的成员函数在类外定义时我用了inline导致的.h和.cpp链接不到,好在解决了,怎么没早点想到让ChatGPT排查错误呢😂😂,学到了,学到了,大家遇到什么问题记得问问AI真的有奇效。

结语

ESP-IDF同样提供了关于C++使用的例程,可以在你电脑中的ESP-IDF安装路径下找到

D:\Espressif\frameworks\esp-idf-v5.2.1\examples\cxx

关于ESP-IDF C++的更多内容可以阅读下下方的官方文档
ESP-IDF C++支持

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

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

相关文章

【NR 定位】3GPP NR Positioning 5G定位标准解读(十五)-UL-TDOA 定位

前言 3GPP NR Positioning 5G定位标准:3GPP TS 38.305 V18 3GPP 标准网址:Directory Listing /ftp/ 【NR 定位】3GPP NR Positioning 5G定位标准解读(一)-CSDN博客 【NR 定位】3GPP NR Positioning 5G定位标准解读(…

Linux:时间指令 - cal date

Linux:时间指令 - cal & date date指令cal指令 date指令 date用于以指定格式显示时间 我们先看看直接输入date指令的效果: [hxyiZ2zehtehrgzt3wqccrpyfZ CSDN]$ date Tue Mar 12 21:38:01 CST 2024直接输入date指令,得到了以 星期 月 日…

C#,数值计算,解微分方程的龙格-库塔二阶方法与源代码

1 微分方程 含有导数或微分的方程称为微分方程,未知函数为一元函数的微分方程称为常微分方程。 微分方程的阶数 微分方程中导数或微分的最高阶数称为微分方程的阶数。 微分方程的解 使得微分方程成立的函数称为微分方程的解。 微分方程的特解 微分方程的不含任意常数的解称…

蚂蚁集团2025届暑期实习开始啦~

蚂蚁集团2025届暑期实习开始啦~欢迎大家投递信贷事业群-风险管理部的算法岗,找我内推哦~社招也有hc,欢迎大家沟通!

STM32CubeIDE基础学习-STM32CubeIDE软件代码编写格式问题

STM32CubeIDE基础学习-STM32CubeIDE软件代码编写格式问题 前言 代码编写最好就是规定一个格式,或者建立一个偏好,这样写出来的代码就方便自己管理了,不然代码乱放下次打开工程就很难找到具体位置,如果规定了格式,那么…

Git 系列:简介安装以及配置管理

文章目录 简介安装简介Centos安装 配置管理[git help](https://www.git-scm.com/docs/git-help)概要选项示例git-doc [git config](https://www.git-scm.com/docs/git-config)概要选项变量示例 初始化配置 简介安装 简介 https://git-scm.com/ Git是一个开源的分布式版本控制…

理论学习:Softmax层和全连接层 全连接层之前的数据

Softmax层和全连接层 Softmax层和全连接层在深度学习模型中通常是紧密相关的,经常一起使用。 全连接层(也称为线性层或密集连接层)是深度学习模型中常见的层之一,它将输入张量与权重矩阵相乘,并添加偏置项,…

酒店宾馆医院IPTV电视系统质保期满后怎样进行维护?-酒店宾馆医院IPTV电视系统质保期满常年巡检售后服务攻略

酒店宾馆医院IPTV电视系统质保期满后怎样进行维护?-酒店宾馆医院IPTV电视系统质保期满常年巡检售后服务攻略 北京海特伟业任洪卓发布于2024年3月11日 一、酒店IPTV电视系统简述 酒店IPTV电视系统,是新时代“互联网”在酒店领域的重要应用之一&#xff…

15双体系Java学习之数组的声明和创建

数组的声明 ★小贴士 可以使用int[] a;或者int a[];建议使用第一种风格,因为它将元素类型int[](整型数组)与变量名清晰分开了。 在Java中声明数组时不能指定其长度。这种定义是非法的:int a[5]; 注意:上图显示的内存…

JDBC连接MysqL

import java.sql.*;public class Demo {public static void main(String[] args) throws ClassNotFoundException, SQLException {//1.注册驱动,加载驱动;Class.forName("com.mysql.jdbc.Driver");//2.获得连接,返回connection类型的对象&…

重学SpringBoot3-集成Thymeleaf

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Thymeleaf 1. 添加Thymeleaf依赖2. 配置Thymeleaf属性(可选)3. 创建Thymeleaf模板4. 创建一个Controller5. 运行应用并访问页…

数学建模-模糊性综合评价模型

中医药是中国传统文化的重要组成部分,凝聚了中华民族千百年来智慧的结晶。作为中医的发源地,中国政府一直致力于保护、发展和推广中医药,采取了一系列政策措施[]。目前,中国面临着老龄化日益加剧,老年人群中慢性疾病和…

在家不无聊,赚钱有门道:5个正规线上赚钱平台,轻松开启副业

随着网络技术的快速发展,越来越多的人开始寻求通过网络来探索兼职副业的可能性,期望实现额外的收入。在这个过程中,选择一个正规且可靠的线上兼职平台显得尤为关键。 为此小编精心网上盘点了5个正规且靠谱的线上兼职副业平台。这些平台不仅安…

双环PID控制详细讲解

参考博客: (1)PID双环控制(速度环和位置环) (2)PID控制(四)(单环与双环PID) (3)内外双环pid算法 0 单环PID 目标位置→系…

Promise图解,Pass

10-优化代码_哔哩哔哩_bilibili

2024年,真的别裸辞....

作为IT行业的大热岗位——软件测试,只要你付出了,就会有回报。说它作为IT热门岗位之一是完全不虚的。可能很多人回说软件测试是吃青春饭的,但放眼望去,哪个工作不是这样的呢?会有哪家公司愿意养一些闲人呢?…

数据结构 第2章:线性表

文章目录 2.1 线性表的定义和操作2.1.1 线性表的基本概念2.1.2 线性表的基本操作 2.2. 顺序表2.2.1. 顺序表的基本概念2.2.2. 顺序表的实现2.2.3. 顺序表的基本操作 2.3 链表2.3.1 单链表的基本概念2.3.2 单链表的实现2.3.3 单链表的插入2.3.4. 单链表的删除2.3.5. 单链表的查找…

mybatis-plus-generator 使用 velocity 生成前后台代码

操作步骤 1)准备mybatis-plus 生成代码的 vm文件 2)添加依赖 mybatis-plus-generator 代码生成器的依赖 3)执行工具方法生成代码 1、准备 mybatis-plus 生成代码的 vm文件 1)找vm模板 去工程的 external Libraries 找到 mybati…

Java SE入门及基础(38)

异常(Exception) 1. 概念 异常 来自官方的说明 An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the programs instructions. 异常是在程序执行期间发生的事件,该事件中断了程序指令的正常流程…

有趣的数学 毕达哥拉斯定理

随便找个学生,让他举出一位著名的数学家——如果他能想到的话,他往往会选择毕达哥拉斯。如果不是,也许他想到的是阿基米德。哪怕是杰出的艾萨克牛顿,在两位古代世界的巨星面前也只能叨陪末座了。阿基米德是一位思想巨人&#xff0…