包含结构的 C 联合 - 内存映射 - 编译器跳过一个字节?
C union containing structs - memory mapping - compiler skips one byte?
我知道标题有点混乱。
我创建了一个包含 "raw" 数组和 2 个结构的联合。这 2 个结构各自包含一个结构 header_t、一个结构联合和一个 uint8_t。我只附加了 inMsg_t,因为两个结构的组成方式相同。
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;
现在,当我 运行 代码时 header-bytes 的内存映射很好。原始数组的 byte[0] 映射到 header-struct 中的 len-field。 cmd0 和 cmd1 也是如此。但是,afRegisterSRSP-struct 中的 "status" 并不指向 status-byte,而是指向状态字节之后的 CRC-Byte。当查看内存地址时,这一点也很清楚。
header 字段位于地址:0x15F6、0x15F7 和 0x15F8。
然后第一个payload-byte在0x15FA处,0x15F9被遗漏了。
我已附上调试器中显示的 screenshot 内存。
我不明白为什么会跳过一个字节以及如何解决它。
payload
联合对齐到四字节边界,而 header
只有三个字节长。这意味着结构的 C 定义中有一个填充字节,但您的内存映射可能已打包,省略了所有填充。您需要使用特定于编译器的标志、编译指示或属性来指定打包各种 unions/structures(以一个字节对齐)以确保不会创建填充字节。例如, and .
此外,根据您的磁盘数据格式,您可能需要小心执行字节交换以从机器本机字节序(通常是小字节序,例如在 x86 上)切换到网络字节序(通常是大字节序,但以下情况除外)一些 Windows 特定协议)。
我知道标题有点混乱。
我创建了一个包含 "raw" 数组和 2 个结构的联合。这 2 个结构各自包含一个结构 header_t、一个结构联合和一个 uint8_t。我只附加了 inMsg_t,因为两个结构的组成方式相同。
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;
现在,当我 运行 代码时 header-bytes 的内存映射很好。原始数组的 byte[0] 映射到 header-struct 中的 len-field。 cmd0 和 cmd1 也是如此。但是,afRegisterSRSP-struct 中的 "status" 并不指向 status-byte,而是指向状态字节之后的 CRC-Byte。当查看内存地址时,这一点也很清楚。
header 字段位于地址:0x15F6、0x15F7 和 0x15F8。
然后第一个payload-byte在0x15FA处,0x15F9被遗漏了。
我已附上调试器中显示的 screenshot 内存。
我不明白为什么会跳过一个字节以及如何解决它。
payload
联合对齐到四字节边界,而 header
只有三个字节长。这意味着结构的 C 定义中有一个填充字节,但您的内存映射可能已打包,省略了所有填充。您需要使用特定于编译器的标志、编译指示或属性来指定打包各种 unions/structures(以一个字节对齐)以确保不会创建填充字节。例如,
此外,根据您的磁盘数据格式,您可能需要小心执行字节交换以从机器本机字节序(通常是小字节序,例如在 x86 上)切换到网络字节序(通常是大字节序,但以下情况除外)一些 Windows 特定协议)。