2010-09-30 10 views
6

umkehren Dies ist ein etwas von einem Follow-up zu this posting aber mit einer anderen Frage, so dass ich fühlte, ich sollte in einem separaten Thread fragen.Wie kann ich die Byte-Reihenfolge eines NSInteger oder NSUInteger in objective-c

Ich bin an dem Punkt, wo ich vier aufeinander folgende Bytes im Speicher habe, die ich aus einer Datei eingelesen habe. Ich möchte diese als ein Bit-Array speichern (der tatsächliche Wert von ihnen spielt keine Rolle bis später). Wenn ich ausdrücke, was in meinem int ist, bemerke ich, dass es in umgekehrter Reihenfolge (Little Endian) gespeichert scheint.

Hat jemand eine gute Methode zum Umkehren der Reihenfolge der Bytes. Dann, einmal umgekehrt, indem aufeinanderfolgende Bits ausgewählt werden, die zwei Bytes umfassen und zurück zu einem int?

unsigned char data[] = { 0x00, 0x02, 0x45, 0x28 }; 
NSInteger intData = *((NSInteger *)data); 

NSLog(@"data:%08x", intData); // data:28450200 

Antwort

15

Kakao (oder genauer der Stiftung Rahmen zu sein) hat die Funktionen der Endian-Byte-Swap: NSSwapInt, NSSwapShort, NSSwapLong und NSSwapLongLong. Diese tauschen die Bytes um, egal was passiert - sie bilden Big-Endian-Integer aus Intensen aus dem kleinen Endian und umgekehrt.

Wenn Sie wissen, welches Format Sie haben, gibt es andere Funktionen, die es mit der nativen Endiannität austauschen: NSSwapLittleIntToHost und NSSwapBigIntToHost. Es gibt auch die umgekehrten Funktionen, die vom nativen Format zum kleinen oder großen Endian-Format wechseln: NSSwapHostIntToLittle und NSSwapHostIntToBig. Diese sind auch für die anderen Integertypen und Gleitkommatypen verfügbar. Was sie tun ist, dass sie bei Bedarf die primitiven Swap-Funktionen auf den Werten aufrufen. So NSSwapLittleIntToHost tut nichts, während NSSwapBigIntToHost das Ergebnis NSSwapInt auf einer kleinen Endian-Maschine zurückgibt.

Beachten Sie, dass diese Parameter der Compiler-Integer-Typen und nicht die NSInteger Art nehmen. Je nachdem, ob Sie 32bit oder 64bit Code generieren, müssen Sie verschiedene Funktionen verwenden, wenn Sie NSInteger verwenden.

Sie sollten auch nicht Ihre Byte-Array auf einen Integer-Zeiger und dereferenzieren. Es wäre besser, die ganze Zahl mit Bit-Shift-Operationen zusammenzusetzen. Ihr Code funktioniert nur, wenn NSInteger 32 Bit breit ist. Wenn es 64 Bit ist, wird Ihre Nummer Müll oder Ihr Programm könnte sogar abstürzen. Aber selbst wenn Sie einen Integer-Typ verwenden, der immer 32 Bit breit ist (int32_t von der C99 <stdint.h> Header zum Beispiel) funktioniert dies möglicherweise nicht wie erwartet.

+0

Danke ich hatte mich ziemlich viel umgesehen und NSSwapBigIntToHost nicht gefunden. Am Ende habe ich etwas weniger manipuliert, wie Sie es vorgeschlagen haben. Ich gehe davon aus, dass meine Ints 32-Bit in meinem Code sein werden. Was ich am Ende getan habe, war ein vorzeichenloses char * tref = (unsigned char *) &temp; Ich Schleife dann durch und tausche die Bytes, dann den Tref auf eine ganze Zahl. Nicht schön, aber funktioniert solange ich 32-Bit bin. – Scott

+0

große Frage und Antwort – LolaRun