Swift 5.1: Unable to pass String to C API

Hello!

I am importing libpostal, a C library which defines a function called libpostal_parse_address. When imported in Swift, this function has the following signature:

func libpostal_parse_address(_ address: UnsafeMutablePointer<Int8>!, 
                             _ options: libpostal_address_parser_options_t) → UnsafeMutablePointer<libpostal_address_parser_response_t>!

The address parameter is a char * in C and imports as a UnsafeMutablePointer<Int8>!—as expected. However, when I try and call this function passing a String for the address parameter, I receive an error:

let res = libpostal_parse_address("some string", options)

Error: "Cannot convert value of type 'String' to expected argument type 'UnsafeMutablePointer?'"

Is String no longer directly convertible to UnsafeMutablePointer<Int8>!? Thanks!

String is not convertible to a mutable pointer, because it wouldn't be safe for C code to mutate a Swift string through the pointer. Can you make the C argument a const char * instead?

1 Like

Got it.

In this case, I would prefer to leave the C code alone as it comes from a library; if I were to modify the C function declarations, I would have to remodify them each time new releases of the library become available.

Sticking with char *, how would I go about converting a Swift String to UnsafeMutablePointer<Int8>!?

You can use String's withCString method to get an UnsafePointer to the C string, then use UnsafeMutablePointer(mutating:) to force it into a mutable pointer.

1 Like