爱恋之燕 发表于 2020-3-25 10:54:23

介绍STM32使用C和C++混合编程的方法,送给有需要的人

本帖最后由 爱恋之燕 于 2020-3-25 11:24 编辑

STM32使用C和C++混合编程的方法,很多网站都有介绍,我在这里重新整理一下,送给有需要的人
使用C++就是为了使用面向对象编程,使用面向对象编程的优势在这里就不多说了,正题开始。
1.使用cubemx生成一个最基本的项目,时钟和SWD配置好就行,这里以MDK为例说明;
2.打开项目,打开魔术棒工具,选择Target选项卡,ARM Compiler改成AC6,将USE MicroLIB去掉,因为C++不支持MicroLIB;

再选择C/C++(AC6)选项卡,把Short enums/wchar选中;

3.STM32的库文件已经做了对C++的兼容支持,每个H文件在开头和结尾都有
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
这样的预编译定义,extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言(而不是C++)的方式进行编译。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。
中断函数定义前也要加上 extern "C";4.再将main.c文件改成main.cpp,再加入项目中,可以看到File Type默认是C++,如果不是请修改,对C++文件,编译器就默认使用C++方式编译;5.此时编译一下应该不会有错误;6.C++有new关键字,类似C的malloc,使用new来新建对象时,默认在堆里面申请内存,可以利用函数重载,重载new操作符,代码如下,将malloc和free换成自己的malloc和free即可。/** Implement C++ new/delete operators using the heap*/
void *operator new(size_t size)
{
       return malloc(size);
}

void *operator new[](size_t size)
{7.环境搭建好了,就可以发挥C++的优势,这里我就牛刀小试,将一个LED抽象为一个对象,先定义类class LED_Class{
      private:
                GPIO_TypeDef *gpio;
                uint16_t pin;
      
      public:成员变量有gpio和pin,用来定义LED的GPIO和PIN,成员函数有init、open、close,分别对LED进行初始化、打开、关闭的操作。使用方法:LED_Class LED1(GPIOA,GPIO_PIN_11);
      LED_Class LED2(GPIOA,GPIO_PIN_12);
      
LED1.init();
LED2.init();
      
      while(1){      
LED1.open();
LED2.open();
HAL_Delay(500);
LED1.close();
LED2.close();
HAL_Delay(500);
      }<span style="background-color: rgb(255, 255, 255);"> </span>这里创建了两个LED对象,可以看到,使用对象操作后,代码逻辑就很简洁,也可以将init函数放到构造函数里,这样在创建对象时,就可以自动初始化GPIO了,还可以将GPIO复位加入析构函数,当对象不用时,自动将GPIO复位,完整代码如下#include "main.h"

/*
* Implement C++ new/delete operators using the heap
*/

void *operator new(size_t size) {
return pvPortMalloc(size);
}

void *operator new[](size_t size) {
return pvPortMalloc(size);
}

void operator delete(void *p) {
vPortFree(p);
}

void operator delete[](void *p) {
vPortFree(p);
}

class LED_Class{
      private:
                GPIO_TypeDef *gpio;
                uint16_t pin;
      
      public:
                LED_Class(GPIO_TypeDef *gpio,uint16_t pin){
                        LED_Class::gpio = gpio;
                        LED_Class::pin = pin;
                }
               
                void init(void){
                        GPIO_InitTypeDef GPIO_InitStruct;
      
                        GPIO_InitStruct.Pin               =         pin;
                        GPIO_InitStruct.Mode               =         GPIO_MODE_OUTPUT_PP;
                        GPIO_InitStruct.Pull               =         GPIO_PULLUP;
                        GPIO_InitStruct.Speed               =         GPIO_SPEED_FREQ_LOW;
                        HAL_GPIO_Init(gpio, &GPIO_InitStruct);
                }
               
                void open(void){
                        HAL_GPIO_WritePin(gpio,pin,GPIO_PIN_RESET);
                }
               
                void close(void){
                        HAL_GPIO_WritePin(gpio,pin,GPIO_PIN_SET);
                }
};

int main(void){
HAL_Init();
      System_ClockConfig();


solita 发表于 2020-3-25 11:12:31

以前做国密SM2加密算法的时候用过C与C++混合编译,方法和你这个有点区别

爱恋之燕 发表于 2020-3-25 11:41:33

#include "main.h"

/*
* Implement C++ new/delete operators using the heap
*/

void *operator new(size_t size) {
return pvPortMalloc(size);
}

void *operator new[](size_t size) {
return pvPortMalloc(size);
}

void operator delete(void *p) {
vPortFree(p);
}

void operator delete[](void *p) {
vPortFree(p);
}

class LED_Class{
      private:
                GPIO_TypeDef *gpio;
                uint16_t pin;
      
      public:
                LED_Class(GPIO_TypeDef *gpio,uint16_t pin){
                        LED_Class::gpio = gpio;
                        LED_Class::pin = pin;
                }
               
                void init(void){
                        GPIO_InitTypeDef GPIO_InitStruct;
      
                        GPIO_InitStruct.Pin               =         pin;
                        GPIO_InitStruct.Mode               =         GPIO_MODE_OUTPUT_PP;
                        GPIO_InitStruct.Pull               =         GPIO_PULLUP;
                        GPIO_InitStruct.Speed               =         GPIO_SPEED_FREQ_LOW;
                        HAL_GPIO_Init(gpio, &GPIO_InitStruct);
                }
               
                void open(void){
                        HAL_GPIO_WritePin(gpio,pin,GPIO_PIN_RESET);
                }
               
                void close(void){
                        HAL_GPIO_WritePin(gpio,pin,GPIO_PIN_SET);
                }
};

int main(void){
HAL_Init();
      System_ClockConfig();
      //LED_Class LED1(GPIOA,GPIO_PIN_11);
       // LED_Class LED2(GPIOA,GPIO_PIN_12);
       //也可以这样 ,这样就是将对象创建在内存池中,而不是栈中
      LED_Class *LED1 = new LED_Class ;
      LED_Class *LED2 = new LED_Class ;
LED1->init();
LED2->init();
      
while(1){      
LED1->open();
LED2->open();
HAL_Delay(500);
LED1->close();
LED2->close();
HAL_Delay(500);
}
}

eric2013 发表于 2020-3-25 11:48:53

谢谢楼主分享。

fyyxxm 发表于 2020-3-25 13:16:19

不错,期待后续教程

wdliming 发表于 2024-1-4 15:06:49

eric2013 发表于 2020-3-25 11:48
谢谢楼主分享。

硬汉哥,你认为单片机用cpp有这个必要嘛?
页: [1]
查看完整版本: 介绍STM32使用C和C++混合编程的方法,送给有需要的人