我收到一些字节,然后我想用相应的值转换为typedef struct
。我的typedef struct
是:
typedef struct SomethingHeader {
uint8_t PV;
uint8_t messageID;
uint32_t stID;
} ;
我收到数组的值:
somePDU[0] = {char} 2 [0x2]
somePDU[1] = {char} 6 [0x6]
somePDU[2] = {char} 41 [0x29]
somePDU[3] = {char} -90 [0xa6]
somePDU[4] = {char} 28 [0x1c]
somePDU[5] = {char} -93 [0xa3]
somePDU[6] = {char} 55 [0x37]
somePDU[7] = {char} -50 [0xce]
somePDU[8] = {char} 0 [0x]
....
当我使用reinterpret_cast<SomethingHeader*>(somePDU)
时,在手表调试模式上我看到:
PV = 2 [0x2]
messageID = 6 [0x6]
stID = -835214564 [0xce37a31c]
reinterpret_cast
跳跃两个字节:somePDU[2]
和somePDU[3]
,但我需要,因为我的期望值是698797623 (0x29a6ce37)
在我看来,reinterpret_cast
只工作得很好,每4个字节(或与结构占用4个字节一行)。
我怎样才能强制reinterpret_cast
不跳过这两个字节?
-
在c++中不能使用
reinterpret_cast
。您将违反类型混叠规则,并且程序的行为将未定义。 -
在标准c++中不能定义没有填充的结构体。在c++中,这样的结构不是一种可移植的表示字节模式的方式。
工作示例:
std::size_t offs = 0;
SomethingHeader sh;
std::memcpy(&sh.PV, somePDU + offs, sizeof sh.PV);
offs += sizeof sh.PV;
std::memcpy(&sh.messageID, somePDU + offs, sizeof sh.messageID);
offs += sizeof sh.messageID;
std::memcpy(&sh.stID, somePDU + offs, sizeof sh.stID);
offs += sizeof sh.stID;
请注意,这仍然假设整数的字节顺序为本机端序,这是一个不可移植的假设。您需要知道源数据的端序,并将其转换为本机字节顺序。这可以通过移位和按位或。
来实现移植。我的问题是padding和字节顺序这些都是对我问题的评论。
我的解决方案是:
#pragma pack(push,1)
struct SomethingHeader {
uint8_t PV;
uint8_t messageID;
uint32_t stID;
};
#pragma pack(pop)
端序只使用ntohl()
。
谢谢