C++ 将消息解析为结构

C++ 将消息解析为结构,c++,c,struct,casting,C++,C,Struct,Casting,我在将消息解析为结构时遇到了一点问题。我知道消息被分成字节,消息的长度总是11字节。有人告诉我,解析数据的一个非常优雅的解决方案是将传入的缓冲区转换为字节结构。我的问题是如何执行该功能。我听说,通过将缓冲区转换为char*,您应该能够在一两行中执行转换 typedef struct tStateMsg { uint8_t reportID; uint8_t ctrlName1; uint8_t State1; uint8_t ctrlName2; uint

我在将消息解析为结构时遇到了一点问题。我知道消息被分成字节,消息的长度总是11字节。有人告诉我,解析数据的一个非常优雅的解决方案是将传入的缓冲区转换为字节结构。我的问题是如何执行该功能。我听说,通过将缓冲区转换为char*,您应该能够在一两行中执行转换

typedef struct tStateMsg {
    uint8_t reportID;
    uint8_t ctrlName1;
    uint8_t State1;
    uint8_t ctrlName2;
    uint8_t State2;
    uint8_t ctrlName3;
    uint8_t State3;
    uint8_t ctrlName4;
    uint8_t State4;
    uint8_t ctrlName5;
    uint8_t State5;
} StateMsg;

void SetState(uint8 msgBuffer[], uint8 bufferSize) //BufferSize is always 11
{
    //Parse the message to the struct.
}
我知道需要进行额外的错误检查,以确保消息始终为11字节长,并且我期望的所有数据都存在,但我将暂时忽略这一点


谢谢你的帮助

这是通过将缓冲区(实际上是缓冲区的起始地址)强制转换为指向结构的指针来实现的:

StateMsg *msg = (StateMsg *)msgBuffer;
然后可以引用
struct
成员

您需要注意的一件事是对齐。如果缓冲区是由
malloc
创建的,则该缓冲区将针对任何数据类型正确对齐。但是,如果缓冲区是一个本地数组,则它可能不会对齐到适合
StateMsg
的边界上

所以一定要使用malloc'ed缓冲区,以解决对齐问题

至于
struct
元素之间的填充,编译器可以在其认为合适的地方自由插入填充。为了确保结构按预期方式放置,您需要将
结构声明为打包。在gcc中,您可以使用
#pragma packed
实现这一点

然而,在实践中,只要将每个元素放置在适当的偏移位置(即,2字节偏移位置为2字节类型,4字节偏移位置为4字节类型),您就应该得到一个按预期布局的结构。在您的特定示例中,所有字段都是1字节,因此除了末尾之外,不应该有任何填充


有关更多详细信息,请参阅(感谢Rob K在评论中提出了这一点)。

如果这里有填充,我会感到惊讶,但请注意,允许编译器在类成员之间添加填充。这意味着<代码> siZeof(tStEnsMg)>=11 < /Cord> C或C++?他们不是同一种语言。我敢肯定,在C++中,dBube的答案是非法的。标记其中一个。不是两个都可以。你看,不,“ASU”,dBube的答案在C++中不是非法的。这是完全合法的。请注意,允许编译器在成员之间插入填充字节,例如对齐。为了实现您的解决方案,必须打包结构。许多编译器都有pragma或选项将结构声明为压缩结构。实际上,对于此结构,由于它都是uint8_t,针对32位代码的编译器只会在结构的末尾添加1个字节,以使其达到32位对齐,使结构的大小为3个32位字,或者如果针对64位代码,将在结构的末尾添加5个字节的填充,使其达到64位对齐,使结构的大小为2个64位字。(参见)。