2014-01-08 57 views
0

所以我有2個結構,級別和項目。當我嘗試讀取一級結構一切正常。但是一旦我嘗試加載一個項目,我的值就會變得混亂。我有了這個十六進制值:NSData結構搞亂數據

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 ... 

將數據讀入一個struct後的值是:

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

您可能需要在結構上設置打包才能打包。在結尾}和你的結構名稱之間添加'__attribute __((packed))'。看看是否有幫助。字節對齊是一種痛苦。 – Putz1103

+0

@ Putz1103,你應該回答。根本問題是對結構成員的對齊沒有默認承諾。請注意,這樣做可能會對性能產生一定的影響(編譯器對齊結構元素的原因......) –

+0

我不認爲'__attribute __((packed))'將會有所幫助。這一切都取決於結構是如何寫入NSData對象以及如何讀*的。 * read *只需要是* write *的* inverse *函數。 – CouchDeveloper

回答

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)]; 
3

您可能需要在您的結構體上設置打包打包。在結尾}和你的結構名稱之間加上__attribute__((packed))。看看是否有幫助。字節對齊是一種痛苦。

typedef struct 
{ 

} __attribute__((packed)) structName; 

如果你是直接從二進制文件中讀取,那麼你要麼需要該文件保存具有相同字節對齊,你正在閱讀,或使文件具有1字節對齊(包裝儘可能小,而不是將緩衝區字節對齊到8或任何其他數字),並將packed屬性添加到結構中。

+0

感謝您的快速回答:) – thomasguenzel