import Foundation extension Array where Element == String { func withCStrings(_ body: ([UnsafePointer]) -> R) -> R { var cStringPtrs: [UnsafePointer] = [] cStringPtrs.reserveCapacity(count) func loop(_ i: Int, _ current: [UnsafePointer], _ body: ([UnsafePointer]) -> R) -> R { if i == count { return body(current) } return self[i].withCString { cstr in var next = current next.append(cstr) return loop(i + 1, next, body) } } return loop(0, [], body) } func withCStringArray(_ body: (UnsafeMutablePointer?>) -> R) -> R { let cStrings = self.map { $0.utf8CString } let pointerArray = UnsafeMutablePointer?>.allocate(capacity: cStrings.count) for (i, cString) in cStrings.enumerated() { cString.withUnsafeBufferPointer { buf in pointerArray[i] = buf.baseAddress } } let result = body(pointerArray) pointerArray.deallocate() return result } }