Reputation: 41
How to a pass a nil pointer to a C API in Swift?
More specifically, I'm trying the following:
import Accelerate
let v = [1.0, 2.0]
var m = 0.0
var sd = 0.0
// 3rd arg is of type: UnsafeMutablePointer<Double>?
vDSP_normalizeD(v, 1, nil, 0, &m, &sd, vDSP_Length(v.count))
Documentation for vDSP_normalizeD
is found here.
This method of passing nil seems valid for earlier versions of Swift as in this answer. However using Xcode v10.1 / Swift v4.2.1 it gives the following error message:
Nil is not compatible with expected argument type 'UnsafeMutablePointer'
The following solution does not work either:
let p: UnsafeMutablePointer<Double>? = nil
vDSP_normalizeD(v, 1, p, 0, &m, &sd, vDSP_Length(v.count))
giving the following error message:
Value of optional type 'UnsafeMutablePointer?' must be unwrapped to a value of type 'UnsafeMutablePointer'
In earlier versions of Swift the following was possible:
let p = UnsafeMutablePointer<Double>(nil)
but it now generates the following error:
Ambiguous use of 'init'
So, my question is - how do I pass a nil pointer to a C API using a modern version of Swift?
Upvotes: 2
Views: 143
Reputation: 41
Problem solved!
Thanks OOPer for verifying that it does in fact compile and asking: Are you doing something special to your project?.
I'm maintaining my project through Swift Package Manager and apparently, when generating the Xcode project, it defaults to MACOSX_DEPLOYMENT_TARGET 10.10. However, creating a new project directly via Xcode v10.1 the default is MACOSX_DEPLOYMENT_TARGET 10.12.
The above code requires 10.11 and I did not understand that SPM didn't use a later deployment target. This is all solved now by using a Package.xcconfig file with the variable: MACOSX_DEPLOYMENT_TARGET=10.11
.
The documentation didn't help from start either. The help for vDSP_normalizeD doesn't mention anything about target requirements, instead that information is found in the documentation for its float cousin vDSP_normalize.
Btw, this might be obvious for some, but it took me some hours to figure it out. Thanks again OOPer for pointing me somewhat in the right direction.
Upvotes: 2
Reputation: 166
it's hard because I could not test it, but I think is because the initializer:
try this:
let p: UnsafeMutablePointer<Double>? = UnsafeMutablePointer<Double>.init(mutating: nil)
And let me know if it works for you
Upvotes: 0