Quick form of the question for those who know Rust: is there a Swift 5 equivalent of std::ffi::CString that can own a String and turn it into a char* like into_raw and later free/drop it using something like from_raw?

Longer version:

I have a C API that I am consuming in Swift. I have to supply a callback function, which I am supplying as a closure argument, and that closure must return a null-terminated string as a const char *—in Swift this is typed as UnsafePointer<Int8>?.

Clearly somebody has to be responsible for that memory and when it will be freed. In this case I would like to say that it is heap-allocated, and Swift is responsible for it and it will keep that const char * alive until the C interface finishes with it and calls some sort of free() function.

What is the least painful way to allocate some memory in Swift initialised with a UTF-8 string, provide a const char * to C, then free it later when instructed?

1 Answers

3
Martin R On Best Solutions

Two possible options:

let swiftString = "Hello world"
swiftString.withCString { cStringPtr in
    // use `cStringPtr` ...

}

calls the closure with a pointer a C string representation of the Swift string (UTF-8 encoded). That pointer is only valid during the execution of the closure.

For a longer lifetime, you can do

let swiftString = "Hello world"
let cStringPtr = strdup(swiftString)
// use `cStringPtr` ...

which allocates a new C String from the given Swift string, and release that memory later with

free(cStringPtr)