我在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)
答案 0 :(得分:3)
我在这里没有掌握一个主要概念吗?
你缺少structure alignment的知识。基本上,它迫使某些字段通过>对齐。 1字节边界取决于它们的大小。您可以使用#pragma
覆盖此行为,但如果在应用程序之外的任何位置使用该结构,则可能会导致互操作性问题。
答案 1 :(得分:2)
我认为问题是对齐。默认情况下,大多数编译器都与机器/ OS的字大小对齐,在本例中为32位/ 4字节。因此,由于您预先有了unsigned char Type字段,编译器会将Size字段推送到下一个偶数4字节边界。
试
#pragma pack 1
在结构定义之前。
我不知道你正在使用什么编译器,但这是一个很好的老式C代码,经常用于网络编程,因为在StackOverflow上大多数这些粗鲁的孩子出生之前就已经开始了。