2

While trying to interface with a C library (Vulkan) I am faced with the following error while trying to assign a Swift(4.2) native String to C String

error: cannot assign value of type 'String' to type 'UnsafePointer<Int8>?'

I'm doing a simple assignment

var appInfo = VkApplicationInfo()
appInfo.pApplicationName = "Hello world"

Wasn't Swift supposed to handle these through its automatic bridging?

Leonardo Marques
  • 3,721
  • 7
  • 36
  • 50
  • Automatic bridging can't help here, because it doesn't solve the memory management problem. You're passing a Swift string to C code that doesn't play by Swift's ARC rules. I think you need to use Unmanaged in this case, but I'm not sure. – Alexander Feb 09 '19 at 20:18
  • @Alexander: `Unmanaged` won't help here, that is only used with *classes* `T`. – Martin R Feb 09 '19 at 20:50

1 Answers1

2

The automatic creation of a C string representation from a Swift String is only done when calling a function taking a UnsafePointer<Int8> argument (compare String value to UnsafePointer<UInt8> function parameter behavior), and the C string is only valid for the duration of the function call.

If the C string is only need for a limited lifetime then you can do

let str = "Hello world"
str.withCString { cStringPtr in
    var appInfo = VkApplicationInfo()
    appInfo.pApplicationName = cStringPtr

    // ...
}

For a longer lifetime you can duplicate the string:

let str = "Hello world"
let cStringPtr = strdup(str)! // Error checking omitted for brevity
var appInfo = VkApplicationInfo()
appInfo.pApplicationName = UnsafePointer(cStringPtr)

and release the memory if it is no longer needed:

free(cStringPtr)
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382