I'm trying to convert a UInt16
array to an UnsafeMutablePointer<UInt16>
in order to call a C function that takes a uint16_t *
from Swift.
If my starting point were [UInt8]
, and my destination UnsafeMutablePointer<UInt8>
, it would all be easy. I could convert the array to Data
, from there to NSData
, call bytes.assumingMemoryBound
, and with that I'd be (almost) done.
However, with the task at hand, there are a couple different paths I'm considering. One approach is converting the [UInt16]
to [UInt8]
, go the same data path as described above, and then specify a different type in the assumingMemoryBound
call.
That is proving to be more involved than anticipated, though. There are a bunch of questions on how to convert an array of just two UInt8
s to one UInt16
; I have found one question asking how to convert a single UInt16
to two UInt8
s, but it all seems to be getting much more involved when converting arrays.
The other approach I'm trying is to simply take the [UInt16]
array value and try converting it to an UnsafeMutablePointer<UInt16>
using an intermediate withUnsafeBytes
call or something of that sort, but Swift has a bunch of different pointer types that just won't match up. Specifically, here's one of my earlier attempts:
array.withUnsafeBytes { (pointer: UnsafeRawBufferPointer) -> UnsafeMutablePointer<UInt16> in
let mutablePointer = UnsafeMutablePointer<UInt16>(mutating: pointer) // error
return mutablePointer
}
That though results in the following error:
Cannot convert value of type 'UnsafeRawBufferPointer' to expected argument type 'UnsafePointer'
Perhaps I just haven't found the right question or the right documentation page yet, so I'd appreciate any pointers in the right direction!
The withXXXBytes
methods get you raw pointers, but here you want a typed pointer. Use withUnsafeMutableBufferPointer
instead and get the base address:
arrayOfUInt16.withUnsafeMutableBufferPointer { (bufferPointer) in
let mutablePointerOfUInt16 = bufferPointer.baseAddress
// do whatever you want with mutablePointerOfUInt16
// just don't "store or return the pointer for later use." as the documentation says
// because the pointer is only valid within this block
}