Create C String Array from Swift

Hello!
I don't know if this is the best way to do it, but I created two helper extensions, one for Collection and another for String. This solution does not require Foundation.

Extension on Collection:

extension Collection {
    /// Creates an UnsafeMutableBufferPointer with enough space to hold the elements of self.
    public func unsafeCopy() -> UnsafeMutableBufferPointer<Self.Element> {
        let copy = UnsafeMutableBufferPointer<Self.Element>.allocate(capacity: self.underestimatedCount)
        _ = copy.initialize(from: self)
        return copy
    }
}

Extension on String:

extension String {
    /// Create UnsafeMutableBufferPointer holding a null-terminated UTF8 copy of the string
    public func unsafeUTF8Copy() -> UnsafeMutableBufferPointer<CChar> { self.utf8CString.unsafeCopy() }
}

Then when creating enabledLayers:

// map over the strings in array, for each string use the string extension
// to get an utf8 "unsafe" copy and get an UnsafePointer to it. Then use
// the Collection extension from above to do an "unsafe" copy of the
// array of UnsafePointers.
let enabledLayers = ["VK_LAYER_LUNARG_standard_validation"]
    .map({ UnsafePointer($0.unsafeUTF8Copy().baseAddress) }).unsafeCopy()

The type of this array will be UnsafeMutableBufferPointer<UnsafePointer<CChar>?>

When you need to use this array as an UnsafePointer<UnsafePointer<CChar>?>! you can just do UnsafePointer(enabledLayers.baseAddress) and because it is a buffer pointer you can get the count with enabledLayers.count.

Hope this helps!

1 Like