【发布时间】:2018-09-26 01:30:58
【问题描述】:
问题仅适用于 C。向量、列表和 C++不解决。
我有接收数据的缓冲区: (从那里和进一步的 U8 是 uin8_t(无符号字符)等等)
数据被打包(它总是有关于开始、结束和长度的信息)。
数据示例(十六进制):
(1 包)
24 0C 00 02 00 00 00 11 AA 0D 78 C8
(2包)
24 0F 00 02 00 00 00 14 D0 07 00 00 0D 7D 53
这里:
'24' - 数据包开始
2 字节的完整数据包长度(粗体)
4字节-特殊ID(这里是02 00 00 00)
1 字节逗号
数据块(标记为粗体)
'0D' - 数据包结束
最后 2 个字节 - CRC
我想使用结构来处理这些数据。
这是我所做的:
typedef __packed struct FM_Packet_s
{
U8 head;
U16 len;
U32 uid;
U8 cmd;
U8 data;
U8 end;
U16 crc;
} FM_Packet_t, *FM_Packet_p;
U8 RX_buff[255];
…
FM_Packet_t *pFM_Packet = (FM_Packet_t *) &RX_buf;
handlerData()
{
// check received CRC
if(pFM_Packet->uid == ID_NUMBER)
{
if(pFM_Packet->cmd == NEEDED_COMMAND)
{
// command received, make actions
if (pFM_Packet->data == SPECIAL_DATA)
{
// do stuff
}
}
}
}
在我收到第二个数据包之前一切都很好,它在 DATA 字段中有超过 1 个字节。 Now data is blended
当然,“数据”字段可能有不同的长度,不仅仅是这两个数据包中显示的那样。
如何处理(正确放入结构中)接收到的数据?
【问题讨论】:
-
我认为 C 不支持结构中间的可变长度数组。我想你只需要直接引用后面的字节,或者为它们定义一个 Packet_Tail 结构,或者其他的东西。
-
不要依赖编译器的结构排列。始终逐段读取数据并将其存储在结构中。当且仅当结构通过相同的可执行文件加载回时,读取和写入原始数据结构才有效。如果是新版本或不同的编译器设置,则该结构可能会转变为不兼容的形式。
-
@tadman 我认为这就是
__packed的用途。 -
@Rup 我只相信这么多,编译器不会像错误对齐的值一样,而且这里还有字节序问题需要处理。
__packed是对编译器的请求,还是硬性要求? -
使用跨编译域的结构我们不可靠,你应该避免这种方法。查看您的数据包结构,没有理由为结构而烦恼,只是为本来不需要任何代码的代码增加了风险和长期维护。