我正在写一个C代码来处理我的温度控制器。我决定学习更多的面向对象编程,学习更多的类,因此这次我选择了C(我通常用C编写代码)。我创建了一个简单的Controller类,其中有我的公共和私有函数。在我的controller.h文件中:
#include "stdint.h"
#include "stdio.h"
#include "params.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#ifdef __cplusplus
extern "C" {
#endif
class Controller
{
private://only accesible for class
int test1;
public:
//accesible outside class
Controller(); // INIT OBJECT
void begin(); // DECLARE DEFAULT
e_thermostat_state Get_state();
void normal_operation_task(void *argument); // FREERTOS TASK FUNCTION PROTOTYPE
};
#ifdef __cplusplus
}
#endif
#endif
在我的控制器里。c:
#include "Controller.h"
Controller controller_obj;
uint8_t app_temp = 10;
Controller::Controller(){
printf("Controller object created \n");
}
void Controller::begin(){
printf("Initialise the object with the default values \n");
xTaskCreate(this->normal_operation_task,"controller normal operation task",10000,NULL,1,NULL);
}
void Controller::normal_operation_task(void *argument){
for(;;)
{
printf("normal_operation_task\n");
vTaskDelay(1000/portTICK_RATE_MS);
}
}
正如您所看到的,当我调用开始方法时,我只想简单地启动任务。我希望freertos任务成为控制器类的一部分的原因是,在这个任务中,我需要访问控制器类的变量和函数。
我得到的错误:
../components/Controller/Controller.cpp: In member function 'void Controller::begin()':
../components/Controller/Controller.cpp:20:98: error: invalid use of non-static member function 'void Controller::normal_operation_task(void*)'
xTaskCreate(this->normal_operation_task,"thermostat normal operation task",10000,NULL,1,NULL); // receiving commands from main uart
有人能给予我一些关于这个的建议吗?我有两个选择:
1.在我的类中,将所有变量和方法声明为public,这样即使freertos任务不是类的一部分,我也可以访问它们。
1.创建task作为Controller类的一部分,以便它可以使用私有方法和变量。
更新
我已经设法这样做时声明静态函数normal_operation_task,我建议我。在controller.h中,我声明:
static void Thermostat::normal_operation_task2(Thermostat* thermostat_obj){
for(;;)
{
printf("normal_operation_task\n");
vTaskDelay(1000/portTICK_RATE_MS);
}
}
我现在试图理解以下几点:
1.为什么这个函数必须声明为static
1.为什么我需要将指针传递给控制器对象?因为它被声明为类方法,所以它可以自动访问类函数和变量
问题
下面的问题是什么,为什么这是错误的?
void Controller::begin(){
printf("Initialise the object with the default values \n");
xTaskCreate(this->normal_operation_task3,"thermostat normal operation task",10000,&controller_obj,1,NULL); //receiving commands from main uart
}
void Controller::normal_operation_task3(void* parameters)
{
Controller controller_obj = *((Controller*)parameters);
for(;;)
{
printf("normal_operation_task\n");
vTaskDelay(1000/portTICK_RATE_MS);
}
}
2条答案
按热度按时间nzk0hqpo1#
关于“为什么我需要将指针传递给我的控制器对象?因为它被声明为类方法,所以它会自动访问类函数和变量,静态方法只能访问类的静态成员。换句话说,静态方法和成员属于类,而不是类的示例。你需要给你的静态方法传递一个指向你的示例的指针,这样才能访问示例及其成员。
至于为什么它一定是一个静态方法,我自己也想知道。
7gs2gvoe2#
FreeRTOS头部有必要的代码(条件extern“C”),使它们与C代码接口-但FreeRTOS通过名称调用的任何回调也需要声明为extern“C”。因此,从C调用xTaskCreate可以工作,但FreeRTOS无法调用您的类方法,因为它没有使用extern“C”声明。您将类声明为extern“C”,但未声明方法(不能将方法声明为extern“C”)。编译器通过名称修改来“检测”这种不匹配(google this以获取更多细节)。
你可以在类的外部创建一个桥接函数(例如作为C-struct的一部分),它持有指向您的控制器类的指针,并且每当FreeRTOS调用此桥接函数时,它都会在指针的帮助下调用您的成员方法。您还可以使用传递给xTaskCreate的参数来保存示例指针。