Luke Pistrol
Luke Pistrol

Reputation: 1209

Swift: Cannot convert value of type 'UnsafeMutablePointer' to expected argument type 'UnsafeMutablePointer'

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?

Upvotes: 10

Views: 28180

Answers (2)

Martin R
Martin R

Reputation: 540065

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()
        return val
    }
}

Upvotes: 8

Ankit Thakur
Ankit Thakur

Reputation: 4749

You can also use below syntax in extension

extension Data {
    func castToCPointer<T>() -> T {
        var bytes = self.bytes
        var val = withUnsafePointer(to: &bytes) { (temp) in
            return unsafeBitCast(temp, to: T.self)
        }
        return val
    }
}

var data:NSData/NSMutableData
var bytes = data.bytes
var val = withUnsafePointer(to: &bytes) { (temp) in
   return unsafeBitCast(temp, to: T.self)
}

Upvotes: -1

Related Questions