今天看程序遇到如下的定义方式实在是不解其意,特查资料充电,将所得与诸位分享:
typedef __packed struct
{
char FileName[8];
char Extension[3];
BYTE Attributes;
BYTE NTReserved;
BYTE CreateTimeTenthSecond;
FS_DOSDateTime CreateDateTime;
WORD LastAccessDate;
WORD FirstClusterHi;
FS_DOSDateTime DateTime;
WORD FirstCluster;
UINT FileSize;
}FS_DOSDirEntry;
__packed应该是编译器的关键字吧。
比如:
typedef struct
{
char x;
int y;
}struct1;
typedef __packed struct
{
char x;
int y;
}struct2;
在32位的ARM SDT编译器中,编译
sizeof(struct1)==8
sizeof(struct2)==5
而处理数据包的时候,lwip使用的就是那种通过结构体指针转换,
读取相应的数据的,所以,一定要在定义struct的时候使用__packed。
似乎,lwip也考虑到了这个问题,所以,在它的结构体定义中
有几个宏。好像是什么PACKED_FIELD_xxx之类的,默认的时候
这几个宏都是空的,可以在移植的时候添加到不同的编译器所需要
的__packed上。可是,一旦定义了__packed的结构体,在使用上
会有很多麻烦。就是因为数据没有32位对齐,操作的时候会出问题。
我觉得这个应该是ARM SDT编译器的问题。
说到_packed,我在实现基于lwip的web server时,
由于编译器不支持,因此没有用_packed关键字来定义struct
和union, 目前跑起来没有问题。
_packed关键字的意思是在struct和union结构中不添加填充字节,如:
struct S
{
char c;
double d;
char e;
};
此处假设char占用1个字节,double占用8个。
则在c后面会有7个字节的填充字节,在e后面也一样。结构体共占用24
个字节。
如果定义:
typedef _Packed struct
{
char c;
double d;
char e;
}
Packed_S;
则该结构体将只占用10个字节。
使用_packed一般会以降低运行性能为代价,由于大多数cpu处理数据
在合适的字节边界数的情况下会更有效,packed的使用会破坏这种自然的
边界数.
本文转自:http://blog.csdn.net/tender_wolf/article/details/3971694
注意,由于语法变化,下面的语法可能编译不通过,需要修改成
typedef _Packed struct
{
char c;
double d;
char e;
}
Packed_S;
#program pack(push,1)
typedef struct
{
char c;
double d;
char e;
}
Packed_S;
#program(pop)