结构体中位段、字节对齐并用的教训
解决了C语言的跨编译器编译,写代码省了不少事儿,今天增加了一条新通讯协议,代码很快就写完了,嗷嗷的爽,只是测试的时候,费了些力气,嗷嗷的郁闷。
为了“省事儿”,我定义了一个结构体,结构体中使用了位段。这个结构体经过宏展开,在ADS下,是这样的:
__packed struct _tag_SwitchConfig
{
uint32 bEnable:1;
uint32 nSignalType:3;
uint32 nTriggerMode:3;
uint32 nThreshold:16;
};
在VC下,是这样的:
#pragma pack(push)
#pragma pack(1)
struct _tag_SwitchConfig
{
uint32 bEnable:1;
uint32 nSignalType:3;
uint32 nTriggerMode:3;
uint32 nThreshold:16;
};
#pragma pack(pop)
结构体定义部分是一模一样的,不同的是有关字节对齐的编译器指令。所以,写这段代码的时候,我没觉得有什么问题。开始测试的时候,我也没觉得有什么问题。但是,测试的结果,却总是不正确。反复检查各个流程的代码,包括数据打包、解包、界面显示,折腾了足足一个多小时,万般无奈之下,分别在两个平台下,执行n=sizeof(struct _tag_SwitchConfig),问题才算露出水面。
居然.......ADS下,n=3,而VC下,n=4。
从编译器的帮助文档里看,__packed以及#pragma pack(1)的意思都是将结构体按1字节对齐。但是__packed正如字面含义一样,可能还有压缩的意思。
我现在的解决办法是增加一个9位的nReserved字段来“充数”,保证两个平台编译结果一致。这个办法的不完美是确定一定以及肯定的了,但是除了位段,还有什么呢?如果你有更好的,不要错过助人为乐的机会:P。
我现在的工作算是沾到跨平台开发的边缘了,需要补充点知识,才能多快好省的完成[请使用文明用语]交给的伟大任务。看了编写跨平台的软件入门--有关字节对齐、关于C结构体bit field的跨平台的教训,尽管收获颇丰,但都没提到我现在的问题。
Copyright © 2008
继续阅读《结构体中位段、字节对齐并用的教训》的全文内容...
分类: 软件开发 | Tags: ARM C 结构体 位段 字节对齐 | 添加评论(0)
相关文章:
Google Code上两个LPC21XX开源项目 (2009-7-4 14:30:32)
基于ARM的网络收音机 (2009-3-24 19:9:11)
显式指针转换的教训 (2009-2-11 18:27:21)
使用结构体中成员变量指针的教训 (2008-9-19 18:30:42)
C语言的跨编译器编译 (2008-8-26 18:38:15)