2016-04-08 13 views
1

ich Daten vom Gerät (BLE) erhielt: < 840100ec d5045715 00.010.014 00.240.018 00>Wie NSData konvertieren struct genau

aber die zweiten Byte nicht genau konvertieren. Wie diese:

enter image description here

Aber ich kann es Uint8 Array verwenden tun, warum? Vielen Dank. enter image description here

Code wie diese:

// I got the data:<840100ec d5045715 00010014 00240018 00> 

    case SPK_FEEDBACK_HistoryDataPort: 
    // Log 
    NSLog(@"receive data:%@", [NSData dataWithBytes:originalCommandBytes length:sizeof(D2MHistoryDataPort)]); 

    // originalCommandBytes dataType:UInt8 * 
    D2MHistoryDataPort *historyData = (D2MHistoryDataPort *)originalCommandBytes; 

    // Log 
    NSLog(@"收到硬件返回的0x%x指令(历史数据体): 历史数据包的索引:%d; 时间戳:%d; 步数:%d; 卡路里:%d; 距离:%d; 睡眠:%d; 运动时长:%d", 
      historyData->cmd, 
      historyData->index, 
      (unsigned int)historyData->timeStamp, 
      historyData->steps, 
      historyData->calories, 
      historyData->distance, 
      historyData->sleep, 
      historyData->duration); 
    break; 

    // I declare this struct in another class 
    typedef struct { 
     UInt8 cmd; 
     UInt16 index; 
     UInt32 timeStamp; 
     UInt16 steps;// 步数 
     UInt16 calories;// 卡路里 
     UInt16 distance;// 距离,单位m 
     UInt16 sleep;// 睡眠 
     UInt16 duration;// 运动时长,单位minute 
    } D2MHistoryDataPort; 
+0

Es ist nicht klar, was Sie fragen. Können Sie den Code anzeigen, auf den Sie die NsData zugreifen? – Paulw11

+0

Vielen Dank für Ihre Freebeck, ich hatte den Code aktualisieren :) –

+0

Es ist immer noch nicht klar, was Ihr Problem ist. Was ist der erwartete Output und wie unterscheidet er sich von dem, was Sie haben? – Paulw11

Antwort

2

Wie der Compiler die einzelnen Felder einer Struktur im Speicher ist abhängig von der Implementierung legt. Normalerweise muss der Compiler Padding hinzufügen, um die Felder richtig auszurichten, und möglicherweise werden sie sogar neu angeordnet (durch Gruppieren von Feldern derselben Größe), um die erforderliche Auffüllung und die Gesamtgröße der Struktur zu reduzieren.

Sie können dieses Verhalten deaktivieren __attribute__((packed)) mit:

typedef struct __attribute__((packed)) { 
    UInt8 cmd; 
    UInt16 index; 
    UInt32 timeStamp; 
    UInt16 steps;// 步数 
    UInt16 calories;// 卡路里 
    UInt16 distance;// 距离,单位m 
    UInt16 sleep;// 睡眠 
    UInt16 duration;// 运动时长,单位minute 
} D2MHistoryDataPort; 
+0

Es funktioniert für mich, vielen Dank. Aber ich habe das ** __ Attribut __ ((gepackt)) ** hinter die 'Struktur' gesetzt. Wenn ich es hinter 'D2MHistoryDataPort' lege, warnt es: 'gepacktes Attribut ignoriert'. Danke noch einmal! –

+0

Gern geschehen. Ich habe das Attribut an den richtigen Ort verschoben. Es ist offensichtlich etwas anders für eine * typedef * gegenüber einer Deklaration ohne * typedef *. Vielen Dank. – Codo

0

Was Sie tun, ist ziemlich garantiert nicht. Sie versuchen, eine Struktur zu nehmen, nehmen an, dass Sie sie als eine Folge von Bytes interpretieren können, schreiben Sie sie und lesen Sie sie zurück. Das wird nicht funktionieren. Beginnend mit Strukturen mit unterschiedlichen Layouts zwischen Compiler-Versionen, zwischen 32- und 64-Bit-Compilern und so weiter. Die Leute wussten in den 90er Jahren, dass das eine schlechte Idee war.

Verwenden Sie das NSCoding-Protokoll. Oder konvertieren Sie die Daten in JSON. Versuchen Sie nicht, Strukturen als eine Folge von Bytes zu interpretieren.

Wenn Sie absolut nicht vermeiden können NSData verwenden, ist dies, wie es sicher funktioniert:

Schritt 1: Definieren Sie das externe Datenformat. Das externe Datenformat ist NICHT "was auch immer der Compiler entschieden hat, um meine Struktur zu strukturieren". Das externe Datenformat ist "Ein unsigniertes Byte cmd; zwei vorzeichenlose Bytes Index, höchstwertiges Byte zuerst. 4 vorzeichenloser Byte-Zeitstempel, höchstwertiges Byte zuerst, dh die Anzahl der Sekunden seit dem 1. Januar 1904, ..." und so weiter.

dann die Struktur zu lesen, einen Zeiger auf das erste Byte erhalten, überprüfen Sie, dass Sie genügend Bytes haben, und

mystruct.cmd = p [0]; 
mystruct.index = (p [1] << 8) | p [2]; 
mystruct.timeStamp = (p [3] << 24) | (p [4] << 16) ... 

und so weiter schreiben.