Search code examples
swiftinteropunsafe-pointers

How to pass argument in Swift to C function that takes an UnsafePointer?


I've imported a C function called geoToH3 that returns an H3Index (which is just a UInt64).

let h3Index = geoToH3(g: UnsafePointer<GeoCoord>!, r: Int32)

The function takes an Int32 and a GeoCoord object, which is just an object with a pair of Double.

let geoCoord = GeoCoord(lat: 45.0, lon: -90.0)

How do I pass the geoCoord argument to this function since it takes an UnsafePointer?


Solution

  • withUnsafePointer(to:) must be used here:

    let h3Index = withUnsafePointer(to: geoCoord) {
         (pointer: UnsafePointer<GeoCoord>) -> H3Index in
         return geoToH3($0, 5)
    }
    

    or shorter (using shorthand parameter syntax and implicit return):

    let h3Index = withUnsafePointer(to: geoCoord) { geoToH3($0, 5) }
    
    • withUnsafePointer(to:) calls the closure with a pointer to the geoCoord value.
    • The C function is called with that pointer as the first argument.
    • The return value from the C function is the return value of withUnsafePointer(to:) and assigned to h3Index.

    It is important that the pointer is only valid during the execution of withUnsafePointer(to:) and must not be stored or returned for later use.

    As an example, the following would be undefined behaviour:

    let pointer = withUnsafePointer(to: geoCoord) { return $0 }
    let h3Index = geoToH3(pointer, 5)