建湖网站建设价格,网站建设 石家庄,黑马培训收费,线上运营推广在ESP-IDF中使用C和C进行混合编译
ESP-IDF是Espressif Systems开发的官方IoT开发框架#xff0c;用于编程和开发ESP32系列的微控制器。虽然ESP-IDF主要使用C语言编写#xff0c;但它也支持使用C进行开发
为什么要进行混合编译#xff1f;
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.cLED.h KEY KEY.cppKEY.h CMakeLists.txt main main.cppCMakeLists.txt components组件下的.cpp/,c和.h
components文件下的CMakeLists.txt指定了该组件的源文件、头文件目录和依赖项。将 LED/LED.c 和KEY/KEY.cpp文件作为源文件LED 和 KEY目录作为头文件目录并将 driver 组件作为依赖项driver组件是在项目中用到的所以要将它加入到依赖项。
idf_component_register(SRCS LED/LED.c KEY/KEY.cppINCLUDE_DIRS LED KEYREQUIRES driver
)main文件下的main.c
第一步 将main文件夹下的main.c重命名为main.cpp
第二步 main文件下的CMakeLists.txt同样只需要将main.c改为main.cpp即可
项目创建自动生成的
idf_component_register(SRCS main.cINCLUDE_DIRS .)修改之后的
idf_component_register(SRCS main.cppINCLUDE_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.h和KEY.h。而void app_main(void)是ESP-IDF为我们提供的主程序我们需要使用extern C来声明这个主程序 #include LED.h
#include KEY.hextern 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
}
#endifKEY.cpp // KEY.cpp#include KEY.hextern 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支持