(C / C ++)包含含有结构的联合的结构......?

时间:2011-04-24 04:58:29

标签: c++ c structure unions

我在linux上编程,这对我来说是新的。我正在开发一个设计'第7层'网络协议的项目,我们有这些包含资源的数据包。并且根据资源的类型,该资源的长度会有所不同。我是C / C ++的新手,我不确定我是否理解工会。我的想法是,我可以创建一个“通用资源”类型,并根据它是什么资源,我可以将一个void *作为指向这个typedef结构的指针,然后调用其中包含的数据作为我喜欢的任何内容它将照顾'铸造'。无论如何,这是我提出的:

typedef struct _pktresource
{
    unsigned char Type; // The type of the resource.

    union {
        struct { // This is used for variable length data.
            unsigned short Size;
            void *Data;
        };

        void *ResourceData; // Just a generic pointer to the data.
        unsigned char Byte;
        char SByte;
        short Int16;
        unsigned short UInt16;
        int Int32;
        unsigned int UInt32;
        long long Int64;
        unsigned long long UInt64;
        float Float;
        double Double;
        unsigned int Time;
    };
} pktresource, *ppktresource;

这背后的原理很简单。但是,当我做像

这样的事情
pktresource.Size = XXXX

它从结构中开始4个字节而不是1个字节。我在这里没有掌握一个主要概念吗?因为感觉就像我。

编辑:忘记提及,当我参考

pktresource.Type

它从一开始就像它应该的那样开始。

编辑:更正是添加编译指示语句以进行正确对齐。修复后,代码如下:

#pragma pack(push)
#pragma pack(1)

typedef struct _pktresource
{
    unsigned char Type; // The type of the resource.

    union {
        struct { // This is used for variable length data.
            unsigned short Size;
            unsigned char Data[];
        };

        unsigned char ResourceData[]; // Just a generic pointer to the data.
        unsigned char Byte;
        char SByte;
        short Int16;
        unsigned short UInt16;
        int Int32;
        unsigned int UInt32;
        long long Int64;
        unsigned long long UInt64;
        float Float;
        double Double;
        unsigned int Time;
    };
} pktresource, *ppktresource;

#pragma pack(pop)

2 个答案:

答案 0 :(得分:3)

  

我在这里没有掌握一个主要概念吗?

你缺少structure alignment的知识。基本上,它迫使某些字段通过>对齐。 1字节边界取决于它们的大小。您可以使用#pragma覆盖此行为,但如果在应用程序之外的任何位置使用该结构,则可能会导致互操作性问题。

答案 1 :(得分:2)

我认为问题是对齐。默认情况下,大多数编译器都与机器/ OS的字大小对齐,在本例中为32位/ 4字节。因此,由于您预先有了unsigned char Type字段,编译器会将Size字段推送到下一个偶数4字节边界。

#pragma pack 1

在结构定义之前。

我不知道你正在使用什么编译器,但这是一个很好的老式C代码,经常用于网络编程,因为在StackOverflow上大多数这些粗鲁的孩子出生之前就已经开始了。