I have a little Problem with my Code after updating to Swift 3. I had this Code before the conversion:
extension NSData {
func castToCPointer<T>() -> T {
let mem = UnsafeMutablePointer<T>.alloc(sizeof(T.Type))
self.getBytes(mem, length: sizeof(T.Type))
return mem.move()
}
}
And I converted it to this Code and in the 3rd line I get an Error
... Cannot convert value of type 'UnsafeMutablePointer' to expected argument type 'UnsafeMutablePointer'
extension Data {
func castToCPointer<T>() -> T{
let mem = UnsafeMutablePointer<T>.allocate(capacity: MemoryLayout<T.Type>.size)
self.copyBytes(to: mem, count: MemoryLayout<T.Type>.size)
//self.copyBytes(to: mem, count: MemoryLayout<T.Type>.size)
return mem.move()
}
}
Does anyone know how to get rid of this?
copyBytes
expects a UnsafeMutableBufferPointer
as argument:
extension Data {
func castToCPointer<T>() -> T {
let mem = UnsafeMutablePointer<T>.allocate(capacity: 1)
_ = self.copyBytes(to: UnsafeMutableBufferPointer(start: mem, count: 1))
return mem.move()
}
}
(allocate()
takes the number of "items" as argument, not the number of
bytes.)
But note that your method leaks memory, the allocated memory
is deinitialized (with move()
) but also has to be
deallocated:
extension Data {
func castToCPointer<T>() -> T {
let mem = UnsafeMutablePointer<T>.allocate(capacity: 1)
_ = self.copyBytes(to: UnsafeMutableBufferPointer(start: mem, count: 1))
let val = mem.move()
mem.deallocate(capacity: 1)
return val
}
}
A simpler solution would be (from round trip Swift number types to/from Data):
extension Data {
func castToCPointer<T>() -> T {
return self.withUnsafeBytes { $0.pointee }
}
}