1

I want to use code from this link which is in swif 2

public protocol SGLImageType {
    typealias Element
    var width:Int {get}
    var height:Int {get}
    var channels:Int {get}
    var rowsize:Int {get}
    
    func withUnsafeMutableBufferPointer(
        @noescape body: (UnsafeMutableBufferPointer<Element>) throws -> Void
    ) rethrows
}

a class implemented above protocol:

final public class SGLImageRGBA8 : SGLImageType { ... public func withUnsafeMutableBufferPointer(@noescape body: (UnsafeMutableBufferPointer<UInt8>) throws -> Void) rethrows {
    try array.withUnsafeMutableBufferPointer(){
        // This is unsafe reinterpret cast. Be careful here.
        let st = UnsafeMutablePointer<UInt8>($0.baseAddress)
        try body(UnsafeMutableBufferPointer<UInt8>(start: st, count: $0.count*channels))
    }
}

in swift 3, the line let st = UnsafeMutablePointer<UInt8>($0.baseAddress) throws this error:

'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type

how to resolve this error?

Community
  • 1
  • 1
xaled
  • 45
  • 1
  • 4
  • Possible duplicate of [Swift 3 UnsafePointer($0) no longer compile in Xcode 8 beta 6](http://stackoverflow.com/questions/39046377/swift-3-unsafepointer0-no-longer-compile-in-xcode-8-beta-6) – kennytm Apr 14 '17 at 16:59
  • @kennytm its not duplicate of that. – xaled Apr 14 '17 at 17:22

1 Answers1

1

You could convert the UnsafeMutableBufferPointer<UInt8> to a UnsafeMutableRawBufferPointer, bind that to UInt8 and create an UnsafeMutableBufferPointer<UInt8> from that (using dummy values here for all the properties):

final public class SGLImageRGBA8 : SGLImageType {
    public var width: Int = 640
    public var height: Int = 480
    public var channels: Int = 4
    public var rowsize: Int = 80
    public var array:[(r:UInt8,g:UInt8,b:UInt8,a:UInt8)] =
        [(r:UInt8(1), g:UInt8(2), b:UInt8(3), a:UInt8(4))]

    public func withUnsafeMutableBufferPointer(body: @escaping (UnsafeMutableBufferPointer<UInt8>) throws -> Void) rethrows {
        try array.withUnsafeMutableBufferPointer(){ bp in
            let rbp = UnsafeMutableRawBufferPointer(bp)
            let p = rbp.baseAddress!.bindMemory(to: UInt8.self, capacity: rbp.count)
            try body(UnsafeMutableBufferPointer(start: p, count: rbp.count))
        }
    }
}

SGLImageRGBA8().withUnsafeMutableBufferPointer { (p: UnsafeMutableBufferPointer<UInt8>) in
    print(p, p.count)
    p.forEach { print($0) }
}

prints

UnsafeMutableBufferPointer(start: 0x000000010300e100, count: 4) 4
1, 2, 3, 4

See UnsafeRawPointer Migration and SE-0107 for more information.

thm
  • 1,217
  • 10
  • 12