Skip to content

Instantly share code, notes, and snippets.

@ctreffs
Created June 10, 2021 07:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ctreffs/788122b5f53f6fd6758f3f89e3e263a6 to your computer and use it in GitHub Desktop.
Save ctreffs/788122b5f53f6fd6758f3f89e3e263a6 to your computer and use it in GitHub Desktop.
[Swift] C-String buffer pointer from array of Strings
extension Array where Element == String {
@inlinable
public func withUnsafeCStringBufferPointer<R>(_ body: (UnsafeBufferPointer<UnsafePointer<CChar>?>) throws -> R) rethrows -> R {
func translate(_ slice: inout Self.SubSequence,
_ offset: inout Int,
_ buffer: UnsafeMutableBufferPointer<UnsafePointer<CChar>?>,
_ body: (UnsafeBufferPointer<UnsafePointer<CChar>?>) throws -> R) rethrows -> R {
guard let string = slice.popFirst() else {
return try body(UnsafeBufferPointer(buffer))
}
return try string.withCString { cStringPtr in
buffer.baseAddress!
.advanced(by: offset)
.initialize(to: cStringPtr)
offset += 1
return try translate(&slice, &offset, buffer, body)
}
}
var slice = self[...]
var offset: Int = 0
let buffer = UnsafeMutableBufferPointer<UnsafePointer<CChar>?>.allocate(capacity: count)
defer { buffer.deallocate() }
return try translate(&slice, &offset, buffer, body)
}
}
@ctreffs
Copy link
Author

ctreffs commented Jun 10, 2021

Usage:

let strings = ["A", "B", "C"]

strings.withUnsafeCStringBufferPointer { buffer in
    for ptr in buffer {
        dump(String(cString: ptr!))   
    }
}

Inspired by https://forums.swift.org/t/can-an-unsafebufferpointer-to-local-scope-array-outlive-its-own-reference/47070/8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment