c++ - 将消息解析为结构

标签 c++ c struct casting

我在将消息解析为结构时遇到了一些麻烦。我知道消息被分成字节,并且消息总是 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 缓冲区以解决对齐问题。

至于struct 元素之间的填充,编译器可以自由地在它认为合适的地方插入填充。为确保结构按照您的预期放置,您需要将 struct 声明为已打包。在 gcc 中,您可以使用 #pragma packed 执行此操作。

但是在实践中,只要您将每个元素放在适当的偏移量处(即 2 字节类型在 2 字节偏移量处,4 字节类型在 4 字节偏移量处),您应该最终得到一个按照您的布局布局的结构预计。在您的具体示例中,您的所有字段都是 1 个字节,因此除了末尾之外不应有任何填充。

有关更多详细信息,请查看 this excellent article on struct packing (感谢 Rob K 在评论中提出这个问题)。

关于c++ - 将消息解析为结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40410179/

相关文章:

c++ - 有什么方法可以使模板函数应用于 C++ 中任意长度的数组?

c++ - 使用Boost Spirit X3解析具有交替标记的Selector结构

c - C 从指向结构体第二个成员的指针获取指向结构体的指针是否合法?

c++ - 成员函数中声明的变量与成员变量相同

c++ - 如何在 Visual Studio 中使用 makefile?

python - 为什么我的模块不能工作,即使我可以导入它?

c - 设置DiGetDeviceRegistryProperty : "The data area passed to a system call is too small" error

c++ - 单个文件上两个 C FILE* 流的一致性

初始化指针 slice 中的 Golang 匿名结构

c++ - 匿名 union 和普通 union