在 C 中为未知(大小)结构创建缓冲区



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

由于我想使其尽可能通用,因此我很想为例如传递任何结构/有效负载成为可能:(这只是一个应该能够传递给函数的结构的示例)

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

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

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

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

我对结构和更高级的东西有点陌生,所以请不要介意我错过一些明显的东西。

通常,此类问题可以通过定义结构来解决,例如:

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);

根据评论和编辑,听起来您的意图是能够将数据传递给某个函数,该函数必须保留数据的副本,直到稍后某个时间点,并且该函数不知道它被要求保留的内容。如果是这种情况,您需要做的就是告诉函数每次调用的长度。例如,void myFunction(const void *buffer, unsigned int length);

myFunction(&myStructOfType1, sizeof(myStructOfType1));
myFunction(&myStructOfType2, sizeof(myStructOfType2));

并且,基于您对重用结构的担忧,myFunction()buffer开始复制到存储内容的任何位置(以及记录它在副本地址存储的长度)length字节以供将来处理。

C 中没有"未知大小的结构"这样的东西。 sizeof(payload_sensor)每次的大小都相同。

您可以将

char[]缓冲区传递到具有任何结构memcpy的函数中。这摆脱了基于结构问题的函数签名。

让按照约定传递的所有结构的第一个结构字节/短/整数持有一个标签,告诉另一端出现什么类型。

如果消息是通过线路(例如UART)发送的,请注意平台之间的字节顺序和不同的sizeof()问题,这些问题可能会使您的协议基于结构进行叶片尝试。

如果您要交换跨平台消息(例如,在PC和AVR之间),则实际上不想处理编译器的不兼容性。在这种情况下,定义记录不基于 C 结构的线路协议,并将字节手动放在 unsigned char 缓冲区中它们所属的位置。或者使用基于 ASCII 的协议。

最新更新