当将指针强制转换为指向包含联合的结构时

发布于 2024-10-20 07:31:06 字数 925 浏览 0 评论 0原文

我对包含联合的结构有疑问。问题是:

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

应该' Length20x101value48

机器是小端字节序。

请帮我解决这个问题...

I have problem with a struct containing union. Here is the problem:

typedef struct
{
    unsigned char Type;                          
    union
    {
        unsigned char Length;
        unsigned __int16 Length2;
    }
    char Value[0];    
} TLV_TUPLE, *PTLV_TUPLE;

If Type == 0x40h, I use Length2, otherwise use Length.

I use this structure to read this file stream (In hex):

FE 01 01 40 12 00 30 …

Now the code:

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

Then as I check the value of pTlv with debugger, I see this:

pTlv->Type == FE
pTlv->Length == 1
pTlv->Length2 == 4001
pTlv->Value == 12

Shouldn't Length2 be 0x101 and value be 48?

machine is little endian.

Please help me with this...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鸠书 2024-10-27 07:31:06

这里发生的情况是,结构被填充了一个额外的字节,以便联合可以正确对齐。

FE 后面的 01 是填充,实际的联合从下一个字节开始。这是因为联合的对齐要求受到其部件的对齐要求的影响。

由于 Length2 需要在两字节边界上对齐,因此在其之前插入一个填充字节以确保发生这种情况。

如果您读入的流是FE FF 01 40 12 00 30 ...,您仍然会得到相同的值。


顺便说一句,我认为“Length2不应该是0101,值不应该是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 或类似的内容来达到相同的目的。

What's happening here is that the structure is being padded with an extra byte so that the union can be correctly aligned.

The 01 following the FE is padding, the actual union starts at the next byte. That's because the alignment requirement for a union is affected by the alignment requirements of its parts.

Since Length2 has a requirement to be aligned on a two-byte boundary, a padding byte is inserted before it to ensure this happens.

If the stream you read in was FE FF 01 40 12 00 30 ..., you would still get the same values.


As an aside, I think "Shouldn’t Length2 be 0101 and value be 48?" should actually have read 64 (0x40) rather than 48 (0x30). I assume that was a typo on your part.


If you need the structure to not have padding, there's no standard way to do it but your compiler should provide a way. For example, you could use something like attributes in gcc:

typedef  struct {
    unsigned char Type;                          
    union {
        unsigned char Length;
        unsigned __int16 Length2;
    }
    char Value[0];    
} __attribute__ ((aligned(1),packed)) TLV_TUPLE;

Other environments may provide a #pragma pack or something similar to acheive the same end.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文