<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Here's how we do it for internal testing purposes: <a href="https://github.com/apple/swift/blob/dfc3933a05264c0c19f7cd43ea0dca351f53ed48/stdlib/private/SwiftPrivate/SwiftPrivate.swift#L68" class="">withArrayOfCStrings</a>. The callback is great because you don't have to worry about lifetimes.</div><div class=""><br class=""></div><div class="">Jordan</div><br class=""><div><blockquote type="cite" class=""><div class="">On Aug 18, 2016, at 13:04, Kenny Leung via swift-users <<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Hi All.<br class=""><br class="">When interfacing with C, Swift does some magic to auto-convert Swift strings to char *. This is great, but passing an array of string pointers gets much more involved. The type translates to UnsafePointer<UnsafePointer<CChar>> in Swift.<br class=""><br class="">So I originally tried to get pointers to the individual strings by using cString(using:), and putting them into an Array, but then I found out that there is nothing holding on to the cStrings, so they go away before they can be used. I finally wound up with this hack:<br class=""><br class="">public extension Array {<br class=""> public func cStringArray() throws -> ArrayBridge<Element,CChar> {<br class=""> return try ArrayBridge<Element,CChar>(array:self) {<br class=""> guard let item = $0 as? String,<br class=""> let translated = item.cString(using: .utf8) else {<br class=""> throw hexdreamsCocoa.Errors.InvalidArgumentError<br class=""> }<br class=""> return translated<br class=""> }<br class=""> }<br class="">}<br class=""><br class="">/*<br class=""> We need to have this intermediate object around to hold on to the translated objects, otherwise they will go away.<br class=""> The UnsafePointer won't hold on to the objects that it's pointing to.<br class=""> */<br class="">public struct ArrayBridge<SwiftType,CType> {<br class=""><br class=""> let originals :[SwiftType]<br class=""> let translated :[[CType]]<br class=""> let pointers :[UnsafePointer<CType>?]<br class=""> public let pointer :UnsafePointer<UnsafePointer<CType>?><br class=""><br class=""> init(array :[SwiftType], transform: (SwiftType) throws -> [CType]) throws {<br class=""> self.originals = array<br class=""> self.translated = try array.map(transform)<br class=""><br class=""> var pointers = [UnsafePointer<CType>?]()<br class=""> for item in translated {<br class=""> pointers.append(UnsafePointer<CType>(item))<br class=""> }<br class=""> pointers.append(nil)<br class=""> self.pointers = pointers<br class=""> self.pointer = UnsafePointer(self.pointers)<br class=""> }<br class="">}<br class=""><br class="">And then to use it you would do something like<br class=""><br class="">try stringArray.cStringArray().pointer<br class=""><br class="">This all seems pretty ugly. So my question is: Is this the right way to handle this problem? Is there a simpler way? It would be awesome if Swift auto-converted arrays of Strings to const char * const *, since it’s a construct used so much in C.<br class=""><br class="">Thanks!<br class=""><br class="">-Kenny<br class=""><br class=""><br class=""><br class="">_______________________________________________<br class="">swift-users mailing list<br class=""><a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-users<br class=""></div></div></blockquote></div><br class=""></body></html>