[Solved] Having issues converting older unsafe API to Swift 4

Hi folks, I have issues converting this old snippet I found on github to Swift 4. I must say that I'm not used to Unsafe* family API, or otherwise I would not bother asking.

The function that requires the pointer looks like this:

@available(OSX 10.3, *)
public func vImageHistogramCalculation_ARGB8888(_ src: UnsafePointer<vImage_Buffer>, _ histogram: UnsafeMutablePointer<UnsafeMutablePointer<vImagePixelCount>?>, _ flags: vImage_Flags) -> vImage_Error

So the code that is not working looks simplified like this:

let array = [UInt](repeating: 0, count: 256)
// error: Cannot invoke initializer for type 'UnsafeMutablePointer<UInt>' with an argument list of type '([UInt])'
let pointer = UnsafeMutablePointer<UInt>(array)

Would be nice if I can get an explanation on how I should fix this issue and convert it to Swift 4.

Actually I just solved it myself :rofl:

var array = [UInt](repeating: 0, count: 256)
let pointer = UnsafeMutablePointer<UInt>(&array)

I'm pretty sure both your solution and the original code are incorrect. The pointer returned from UnsafeMutablePointer<UInt>(&array) is not guaranteed to be a valid pointer into the array's elements after the call returns.

You can use the &array shorthand for passing a pointer to the array elements to a single function, but you can't count on the pointer being valid after the function returns.

If you need a pointer with a longer lifetime, you should use array.withUnsafeMutableBufferPointer(_:) and perform the pointer operations inside the function you pass in.

7 Likes