如果结构未正确对齐,我如何访问结构的成员?

时间:2011-01-08 18:16:15

标签: c cocoa macos data-structures

我担心我不擅长低级C的东西,我比较习惯 使用Obj-c中的对象,如果这是一个明显的问题,或者如果我完全误解了某些内容,请原谅我......

我试图在Cocoa / Obj-C中编写一个应用程序,它与外部硬件进行通信(现金直到。)我有设备发送和接收的数据格式 - 并成功获得了一些块来自设备的数据。

例如:直到以下列格式交换数据块中的PLU(价格数据):(来自文档)

名称字节类型

Name             Bytes    Type

PLU code h        4      long   
PLU code L        4      long
desc              19     char
Group             3      char
Status            5      char 
PLU link code h   4      long 
PLU link code l   4      long
M&M Link          1      char
Min. Stock.       2      int
Price 1           4      long 
Price 2           4      long

Total 54 Bytes

所以我有一个以下形式的结构来保存数据:

typedef struct MFPLUStructure { 
 UInt32   pluCodeH; 
 UInt32   pluCodeL; 
 unsigned char description[19]; 
 unsigned char group[3]; 
 unsigned char status[5]; 
 UInt32   linkCodeH; 
 UInt32   linkCodeL; 
 unsigned char mixMatchLink; 
 UInt16   minStock; 
 UInt32   price[2];  
} MFPLUStructure;  

我有一些来自直到(下面)的已知样本数据,我手动检查并且有效

<00> 00 00 00 00 4E 61 BC 00 54 65 73 74 20 50 4C 55 00 00 00 00 00 00 00 00 00 00 09 08 08 17 13 7C 14 04 00 00 00 00 09 03 00 00 05 BC 01 7B 00 00 00 00 00 00 00

即。

  • 字节46到50是<7B 00 00 00> == 123正如我所期望的那样,因为价格设置为“123”。

  • 字节43是<05> == 5,正如我所期望的那样,“混合和匹配链接”在直到设置为5。

  • 字节39到43是<09 03 00 00> == 777正如我所期望的那样,因为“链接代码”设置为“777”。

  • 字节27,28,29是<09 08 07>,这是我期望的三组(7,8和9)。

当我尝试以编程方式从结构中获取一些数据时出现问题:早期成员正常工作,包括五个“状态”字节。但是,之后的成员不能正常出来。 (参见下面的调试器截图。)

图片1 - http://i.stack.imgur.com/nOdER.png

我认为这是因为五个状态字节推动后面的成员不对齐 - 即它们超过机器字边界。这是对的吗?

图片2 - i.imgur.com/ZhbXU.png

我是否正确地做出这样的假设? 如果是这样,我怎样才能让成员正确进出?

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

一次一个字节地访问数据并将其组装成更大的类型,或者memcpy将其组合成一个对齐的变量。如果已知数据的格式特定于主机的字节序等,后者会更好。如果数据遵循可能与主机不匹配的外部规范,前者会更好。

答案 1 :(得分:1)

如果您确定主机和线路的字节顺序一致,您也可以使用压缩结构一次读取数据。但是,这是特定于编译器的,很可能会影响成员访问的性能。

假设gcc,您将使用以下声明:

struct __attribute__ ((__packed__)) MFPLUStructure { ... };
typedef struct MFPLUStructure MFPLUStructure;

如果您决定使用打包结构,还应验证其大小是否正确:

assert(sizeof (MFPLUStructure) == 54);