我目前正在为RF24Mesh微控制器层编写一个抽象层来实现消息签名。
由于我希望尽可能地使其普及,我希望能够为ex传递任何结构/有效负载:(这只是一个结构应该能够传递给功能)
struct payload_sensor {
uint8_t some_other_sensor_data[32];
int sensor_id;
int sensor_data;
};
到签名函数,然后让它处理存储有效负载/结构,直到完成所有其他操作。
但事实上,我无法预测传递给函数的结构的确切大小(它应该处理传递给它的任何结构),同样的结构可能会被重用(填充其他数据)并再次传递给该函数。我完全无法想出一个好的解决方案。
现在,我如何实现一个适当的缓冲区来存储这些未知的有效负载/结构,直到它们准备发送为止?我还必须记住代码在AVR上运行,因此AVR内存(碎片)可能会成为问题。
我是一种新的结构和更高级的东西,所以不要忘记我错过了一些明显的东西。
答案 0 :(得分:4)
通常通过定义结构来解决这类问题,例如:
struct payload_sensor {
unsigned int struct_size;
int sensor_id;
type any_other_always_present_data;
char variable_data[];
};
其中variable_data
是您有效负载的未知部分。
当您知道实际variable_data
需要多大时,您可以执行以下操作:
unsigned int actual_length = length_of_variable_data + sizeof(struct payload_sensor);
struct payload_sensor *myStruct = malloc(actual_length);
myStruct->struct_size = actual_length;
并将您的变量数据复制到结构中:
memcpy(&myStruct->variable_data, &data_source, length_of_variable_data);
基于评论和编辑,听起来你的意图是能够将数据传递给某些必须保留数据副本的函数,直到稍后的某个时间点,并且该函数不知道它的内容#39;被要求举行。如果是这种情况,您需要做的就是告诉函数每次调用的长度。例如,void myFunction(const void *buffer, unsigned int length);
:
myFunction(&myStructOfType1, sizeof(myStructOfType1));
myFunction(&myStructOfType2, sizeof(myStructOfType2));
并且,基于您对重用结构的关注,从myFunction()
开始length
复制buffer
个字节到存储内容的任何位置(以及记录存储的长度)在副本的地址)以供将来处理。
答案 1 :(得分:2)
没有类似于"未知大小的结构"在C. sizeof(payload_sensor)
中每次都会有相同的大小。
答案 2 :(得分:1)
您可以将newmsg.Send 'send message
newmsg.DeleteAfterSubmit = True
缓冲区传递给具有任何结构newmsg.DeleteAfterSubmit = True
newmsg.Send 'send message
的函数。这消除了基于struct问题的函数签名。
按惯例传递的所有结构的第一个struct byte / short / int都包含一个标记,告诉另一个结束了什么类型。
如果消息是通过线路(例如UART)发送的,请注意平台之间的字节顺序和不同的char[]
问题,这些问题可能会使基于结构的协议成为风向标尝试。
如果您正在交换跨平台消息(例如,在PC和AVR之间),您真的不想处理编译器不兼容问题。在这种情况下,定义和文档一个不基于C结构的线路的协议,并将它们所属的字节手动放在memcpy
中缓冲。或者使用基于ASCII的协议。