2016-09-08 19 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的数字,没有区别。 - 通常情况下,传感器数据必须乘以一些浮点数才能得到“实际”值,应该记录在设备中,不存在“通用公式”。 –

相关问题