NSData to Struct搞乱数据

时间:2014-01-08 15:06:28

标签: ios objective-c cocoa struct nsdata

所以我有2个结构,Level和Item。当我尝试读取级别结构时,一切正常。但是一旦我尝试加载一个项目,我的价值就搞砸了。我有这个十六进制值:

    Level-Struct| Item-Struct 
    spRot|count | type | anchorX: 25 | anchorY:375 |count
... 00 00 05 00   00 00 19 00   00 00 77 01   00 00 04 00 ...

将数据读入结构后,值为:

type = 0
anchorX = 24576000
anchorY = 262144
pointCount = 0

似乎它用0填充“填充”类型,然后继续使用00 00 77 01(这是24576000)而不是正确的19 00 00 00(25)。我怎样才能让我的程序正确读取它?以下是来源的重要部分:

typedef struct ItemPoint {
    SInt32 x;
    SInt32 y;
} ItemPoint;

typedef struct Item {
    UInt16 type;
    UInt32 anchorX;
    UInt32 anchorY;
    UInt32 pointCount;
    ItemPoint *points;
} Item;

typedef struct LevelStruct {
    UInt32 width;
    UInt32 height;
    UInt32 spawnX;
    UInt32 spawnY;
    UInt16 spawnRot;
    UInt16 itemCount;
    void *items;
} LevelStruct;



// Test Function

LevelStruct level;
NSUInteger byteOffset = 20;
[data getBytes:&level length:byteOffset];
BlockPolygon *poly = malloc(sizeof(BlockPolygon));
[data getBytes:poly range:NSMakeRange(byteOffset, 14)];

2 个答案:

答案 0 :(得分:3)

如果你想编组你的结构,你应该将它们声明为打包并使用sizeof而不是幻数。

typedef struct __attribute__((__packed__)) ItemPoint {
    SInt32 x;
    SInt32 y;
} ItemPoint;

typedef struct __attribute__((__packed__)) Item {
    UInt16 type;
    UInt32 anchorX;
    UInt32 anchorY;
    UInt32 pointCount;
    ItemPoint *points;
} Item;

typedef struct __attribute__((__packed__)) LevelStruct {
    UInt32 width;
    UInt32 height;
    UInt32 spawnX;
    UInt32 spawnY;
    UInt16 spawnRot;
    UInt16 itemCount;
    void *items;
} LevelStruct;



// Test Function    
LevelStruct level;
size_t length = sizeof(LevelStruct);
size_t offset = 0;

[data getBytes:&level length:length];

offset += length;
length = sizeof(BlockPolygon);

BlockPolygon *poly = malloc(length);
[data getBytes:poly range:NSMakeRange(offset, length)];

答案 1 :(得分:3)

您可能需要将结构上的打包设置为打包。在结尾}和结构名称之间添加__attribute__((packed))。看看是否有帮助。字节对齐是一种痛苦。

typedef struct
{

} __attribute__((packed)) structName;

如果您直接从二进制文件中读取,则需要使用与读取时相同的字节对齐来保存该文件,或者使文件的字节对齐为1(尽可能小地打包,而不是缓冲区字节对齐到8或任何其他数字)并将packed属性添加到结构中。