C语言 为什么我可以传递一个整数作为任务参数,但不能传递一个结构变量?

cgvd09ve  于 2023-11-16  发布在  其他
关注(0)|答案(1)|浏览(106)

我试图将一组参数传递给任务。所以我创建了一个结构体并将其传递给我的任务,如下所示:

my_type_t parameters_set;

//... assigning values to parameters_set

xTaskCreate( vMyTask, "MyTask", STACK_SIZE, (void*)parameters_set, 2,
 &xHandle);

字符串
在我的任务中,我尝试检索结构体值,执行以下操作:

my_type_t received_parameters = (my_type_t) pvParameters;


任务创建行在编译时触发以下错误:“cannot convert to a pointer type”and the struct retrieving line triggers the“Conversion to non-scalar type requested”error.我知道如果我使用指针而不是变量本身,它会编译,但我不能这样做,因为创建任务的函数将死亡,任务将引用一个不再存在的变量。最后我将使用一个全局结构变量。

但我真正想理解的是为什么任务接受int值(而不是引用),而不接受typedef结构体?例如,下面的代码片段构建和工作没有问题:

//Inside the function that creates the task
int x = 0;

xTaskCreate( vMyTask, "MyTask", STACK_SIZE, (void*)x, 2,
 &xHandle);

//Inside the Task
int received_parameter = (int) pvParameters;


提前感谢!

siv3szwd

siv3szwd1#

您所展示的代码没有将int值作为参数。您使用(void*)x传递参数,这是一个将intx转换为指针的表达式。
函数xTaskCreate接受一个指针。你已经给了它一个指针,所以编译器不会抱怨。但是,你给它的指针不是指向**x的指针(将被写为&x),但它是从**x的值转换而来的指针**。尽管编译器没有抱怨,这通常不是传递给xTaskCreate的正确事情。
这不适用于结构体的原因是,当parameters_set是一个结构体时,(void*)parameters_set不是一个正确的表达式。这是因为C提供了将整数转换为指针,但不提供将结构体转换为指针。通常,整数和指针之间存在自然的对应关系:在“平面”地址空间中,内存中的每个字节都有一个地址,这些地址本质上是从内存地址空间的“开始”开始的字节计数。因此,整数可以作为地址,反之亦然。(在其他地址空间中,对应关系可能更复杂,但C仍然允许转换,但有一些规则。)因此,当您编写(void*)x时,编译器将x中的整数值转换为指针。
在结构和指针之间没有这样的对应关系,所以C标准没有定义任何从结构到指针的转换,当你写(void*)parameters_set时编译器会抱怨。
你应该为这个参数传递的是**要给任务的一些数据的地址。如果你想让任务有x的数据,你应该传递&x。如果你想让任务有parameters_set的数据,你应该传递&parameters_set&运算符接受它的操作数的地址,这与使用(void*)强制转换不同,后者试图将其操作数转换为指针。
根据RTOS documentation for xTaskCreate,你不应该传递一个“栈变量”的地址,这实际上意味着,对于C,一个具有自动存储持续时间的对象。换句话说,你不应该传递一个在没有staticparameters_set的函数中定义的xparameters_set。(可能,取决于RTOS和C实现的安排;我不熟悉RTOS)_Thread_local。或者,您可以使用malloc为参数分配空间(或者,根据下面的注解,RTOS的pvPortMalloc)并将其传递给xTaskCreate

相关问题