我对包含union的结构有问题。这是问题所在:
typedef struct
{
unsigned char Type;
union
{
unsigned char Length;
unsigned __int16 Length2;
}
char Value[0];
} TLV_TUPLE, *PTLV_TUPLE;
如果Type == 0x40h
,我使用Length2
,否则请使用Length
。
我使用此结构来读取此文件流(十六进制):
FE 01 01 40 12 00 30 …
现在代码:
unsigned char * m_pTLV;
/*code here to let m_pTLV points to the
first byte of the file, that is, point to 'FE' */
PTLV_TUPLE pTlv = (PTLV_TUPLE)m_pTLV; // cast m_pTLV to PTLV_TUPLE
然后当我用调试器检查pTlv的值时,我看到了:
pTlv->Type == FE
pTlv->Length == 1
pTlv->Length2 == 4001
pTlv->Value == 12
Length2
0x101
和value
48
不应该是{{1}}吗?
机器是小端。
请帮帮我...
答案 0 :(得分:2)
这里发生的是结构用一个额外的字节填充,以便联合可以正确对齐。
01
之后的FE
是填充,实际联合从下一个字节开始。这是因为联合的对齐要求受其各部分的对齐要求的影响。
由于Length2
需要在双字节边界上对齐,因此在它之前插入填充字节以确保发生这种情况。
如果您输入的信息流为FE FF 01 40 12 00 30 ...
,您仍会获得相同的值。
顺便说一句,我认为"Shouldn’t Length2 be 0101 and value be 48?"
实际上应该阅读64 (0x40)
而不是48 (0x30)
。我认为这是你的错字。
如果需要结构没有填充,那么没有标准方法可以做到这一点,但是你的编译器应该提供一种方法。例如,您可以使用gcc
中的属性:
typedef struct {
unsigned char Type;
union {
unsigned char Length;
unsigned __int16 Length2;
}
char Value[0];
} __attribute__ ((aligned(1),packed)) TLV_TUPLE;
其他环境可能提供#pragma pack
或类似的东西来实现同一目的。