2016-09-08 53 views
3

我獲得磁力調整寄存器爲獲得NSData的()(如下所示):如何NSData的轉換爲多類型INTS

<00001a1a 4f56f202 00000000 1dfd421b>

我需要將其轉換爲INT8,UINT8,Int16的,UINT16視我訪問哪個字節。從文檔

來源:

s8 dig_x1;/**< trim x1 data */ 
s8 dig_y1;/**< trim y1 data */ 

s8 dig_x2;/**< trim x2 data */ 
s8 dig_y2;/**< trim y2 data */ 

u16 dig_z1;/**< trim z1 data */ 
s16 dig_z2;/**< trim z2 data */ 
s16 dig_z3;/**< trim z3 data */ 
s16 dig_z4;/**< trim z4 data */ 

u8 dig_xy1;/**< trim xy1 data */ 
s8 dig_xy2;/**< trim xy2 data */ 

u16 dig_xyz1;/**< trim xyz1 data * 

enter image description here

的主要問題是如何在NSData的訪問選擇的字節將其手動轉換要麼INT8或UIint16等?

一般來說,如何解決這樣的問題?應該尋找一種方式來手動迭代NSData並將每個值手動轉換爲?

回答

4

您可以轉換data.bytes + offset到 適當類型的指針,然後取消引用指針:

let dig_x1 = UnsafePointer<Int8>(data.bytes).memory 
let dig_y1 = UnsafePointer<Int8>(data.bytes + 1).memory 
// ... 
let dig_z1 = UnsafePointer<UInt16>(data.bytes + 4).memory 
let dig_z2 = UnsafePointer<Int16>(data.bytes + 6).memory 
// ... 

(注:這裏假設在二進制BLOB所有值都爲 屬性對齊它們類型)。

數據採用little-endian字節順序,這也是當前iOS平臺使用的所有 。爲了安全起見,轉換 數據到主機明確字節順序:

let dig_z1 = UInt16(littleEndian: UnsafePointer(data.bytes + 4).memory) 
let dig_z2 = Int16(littleEndian: UnsafePointer(data.bytes + 6).memory) 
// ... 

一個替代方案是在橋接報頭文件

struct MagnetometerData { 
    int8_t dig_x1; 
    int8_t dig_y1; 

    int8_t dig_x2; 
    int8_t dig_y2; 

    uint16_t dig_z1; 
    int16_t dig_z2; 
    int16_t dig_z3; 
    int16_t dig_z4; 

    uint8_t dig_xy1; 
    int8_t dig_xy2; 

    uint16_t dig_xyz1; 
} ; 

,以限定一個C結構,並且在一個提取數據步驟:

var mdata = MagnetometerData() 
data.getBytes(&mdata, length: sizeofValue(mdata)) 

這適用(如果在結構成員之間沒有填充) 因爲夫特保留結構的佈局從C.


進口一種可能夫特3實施第一種方法的是

let dig_x1 = ((data as NSData).bytes).load(as: Int8.self) 
let dig_y1 = ((data as NSData).bytes + 1).load(as: Int8.self) 
// ... 
let dig_z1 = ((data as NSData).bytes + 4).load(as: UInt16.self) 
let dig_z2 = ((data as NSData).bytes + 6).load(as: Int16.self) 
// ... 

再次假設所有值是屬性爲其 類型對齊。

+0

非常感謝!還有一個小問題:使用您發佈的z1的方法評估爲22095,對於磁力儀調整寄存器中的z1是否合理且可能的值?另外,它的UInt16或Int16值仍然相同,是否正確? – DCDC

+0

它關注我,無論我是否設置爲UInt16或Int16,結果都是一樣的,對於補碼是否正確? – DCDC

+0

@DCDC:對於範圍爲0..32767的數字,沒有區別。 - 通常情況下,傳感器數據必須乘以一些浮點數才能得到「實際」值,應該記錄在設備中,不存在「通用公式」。 –

相關問題