首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C联合包含结构-内存映射-编译器跳过一个字节?

C联合包含结构-内存映射-编译器跳过一个字节?
EN

Stack Overflow用户
提问于 2016-06-16 12:43:01
回答 1查看 801关注 0票数 2

有点混乱的标题,我知道。

我创建了一个包含“原始”-array和2个结构的联合。这两个结构每个包含一个结构header_t,一个结构的联合和一个uint8_t。我只附加了inMsg_t,因为这两个结构都是以相同的方式组成的。

代码语言:javascript
复制
typedef struct sAfRegisterSRSP{
    uint8_t Status;
} tAfRegisterSRSP;

typedef union InOutMsg_u{
    uint8_t raw[ZIGBEE_PAYLOAD_MAX];
    outMsg_t outMsg;
    inMsg_t inMsg;
}msg_t;   


typedef struct header_s{
    uint8_t len;    ///< packet len 
    uint8_t cmd0;   ///< type (Bit: 7-5) and subsystem (Bit 4-0))
    uint8_t cmd1;   ///< command identifier
}header_t;


typedef struct inMsg_s{
    header_t header;
    union payload_u{
        tAfRegisterSRSP               afRegisterSRSP;
        tAfDataRequestSRSP            afDataRequestSRSP;
        tAfIncomingMsgAREQ            afIncomingMsgAREQ;
        tAfDataConfirmAREQ            afDataConfirmAREQ;

        tZbStartRequestSRSP           zbStartRequestSRSP;
        tZbPermitJoiningRequestSRSP   zbPermitJoiningRequestSRSP;
    } payload;
    uint8_t checksum;   //just a placeholder; cannot be used practically
}inMsg_t;

现在,当我运行代码时,头字节的内存映射是可以的。原始数组的字节映射到标头-结构中的len-字段。cmd0和cmd1也是。但是,afRegisterSRSP-struct中的“状态”并不指向状态-字节,而是指向CRC- byte,即状态字节之后。在查看内存地址时,这一点也很清楚。

头字段位于地址: 0x15F6、0x15F7和0x15F8。

然后,第一个有效负载字节位于0x15FA,而0x15F9被忽略。

我已经附加了内存的屏幕截图,如调试器中所示。

我不知道为什么跳过一个字节,以及如何修复它。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-16 12:48:22

payload联合被对齐到一个四字节的边界,而header只有三个字节长。这意味着结构的C定义中有一个pad字节,但是您的内存映射可能是打包的,忽略了所有的填充。您需要使用编译器特定的标志、杂注或属性来指定各种联合/结构打包(到一个字节对齐),以确保不创建填充字节。例如,打包Visual Studio包装

此外,根据磁盘数据格式,您可能需要小心地执行字节交换,以便从机器本机endianness (通常是在x86上)切换到网络endianness (通常为大端,少数特定于Windows的协议除外)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37859601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档