Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get bytes out of an UnsafeMutableRawPointer?

How does one access bytes (or Int16's, floats, etc.) out of memory pointed to by an UnsafeMutableRawPointer (new in Swift 3) handed to a Swift function by a C API (Core Audio, etc.)

like image 410
hotpaw2 Avatar asked Aug 16 '16 19:08

hotpaw2


2 Answers

load<T> reads raw bytes from memory and constructs a value of type T:

let ptr = ... // Unsafe[Mutable]RawPointer let i16 = ptr.load(as: UInt16.self) 

optionally at a byte offset:

let i16 = ptr.load(fromByteOffset: 4, as: UInt16.self) 

There is also assumingMemoryBound() which converts from a Unsafe[Mutable]RawPointer to a Unsafe[Mutable]Pointer<T>, assuming that the pointed-to memory contains a value of type T:

let i16 = ptr.assumingMemoryBound(to: UInt16.self).pointee 

For an array of values you can create a "buffer pointer":

let i16bufptr = UnsafeBufferPointer(start: ptr.assumingMemoryBound(to: UInt16.self), count: count) 

A buffer pointer might already be sufficient for your purpose, it is subscriptable and can be enumerated similarly to an array. If necessary, create an array from the buffer pointer:

let i16array = Array(i16bufptr) 

As @Hamish said, more information and details can be found at

  • SE-0107 UnsafeRawPointer API
like image 147
Martin R Avatar answered Sep 20 '22 15:09

Martin R


Here's a Swift 4 example of converting a literal UInt8 array to an UnsafeMutableRawPointer and back to an UInt32 array

static func unsafePointerTest() {     //let a : [UInt8] = [0,0,0,4,0,0,0,8,0,0,0,12]     let a : [UInt8] = [0x04, 0x00, 0x00, 0x00,                        0x08, 0x00, 0x00, 0x00,                        0x0C, 0x00, 0x00, 0x00] //little endian     //0xFF, 0xF0, 0xF0, 0x12]  //317780223 = 12F0F0FF     let b:UnsafeMutableRawPointer = UnsafeMutableRawPointer(mutating:a)     let bTypedPtr = b.bindMemory(to: UInt32.self, capacity: a.count/4)     let UInt32Buffer = UnsafeBufferPointer(start: bTypedPtr, count: a.count/4)     let output = Array(UInt32Buffer)     print(output) } 
like image 41
Mike Lee Avatar answered Sep 18 '22 15:09

Mike Lee