在C

时间:2016-04-26 21:02:41

标签: c struct

我目前正在为RF24Mesh微控制器层编写一个抽象层来实现消息签名。

由于我希望尽可能地使其普及,我希望能够为ex传递任何结构/有效负载:(这只是一个结构应该能够传递给功能)

  struct payload_sensor {
        uint8_t some_other_sensor_data[32];
        int sensor_id;
        int sensor_data;
  };

到签名函数,然后让它处理存储有效负载/结构,直到完成所有其他操作。

但事实上,我无法预测传递给函数的结构的确切大小(它应该处理传递给它的任何结构),同样的结构可能会被重用(填充其他数据)并再次传递给该函数。我完全无法想出一个好的解决方案。

现在,我如何实现一个适当的缓冲区来存储这些未知的有效负载/结构,直到它们准备发送为止?我还必须记住代码在AVR上运行,因此AVR内存(碎片)可能会成为问题。

我是一种新的结构和更高级的东西,所以不要忘记我错过了一些明显的东西。

3 个答案:

答案 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的协议。