<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:&nbsp;<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 &lt;<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>&gt; 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&lt;UnsafePointer&lt;CChar&gt;&gt; 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=""> &nbsp;&nbsp;&nbsp;public func cStringArray() throws -&gt; ArrayBridge&lt;Element,CChar&gt; {<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return try ArrayBridge&lt;Element,CChar&gt;(array:self) {<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;guard let item = $0 as? String,<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let translated = item.cString(using: .utf8) else {<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw hexdreamsCocoa.Errors.InvalidArgumentError<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return translated<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br class=""> &nbsp;&nbsp;&nbsp;}<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&lt;SwiftType,CType&gt; {<br class=""><br class=""> &nbsp;&nbsp;&nbsp;let originals &nbsp;:[SwiftType]<br class=""> &nbsp;&nbsp;&nbsp;let translated :[[CType]]<br class=""> &nbsp;&nbsp;&nbsp;let pointers &nbsp;&nbsp;:[UnsafePointer&lt;CType&gt;?]<br class=""> &nbsp;&nbsp;&nbsp;public let pointer &nbsp;&nbsp;&nbsp;:UnsafePointer&lt;UnsafePointer&lt;CType&gt;?&gt;<br class=""><br class=""> &nbsp;&nbsp;&nbsp;init(array :[SwiftType], transform: (SwiftType) throws -&gt; [CType]) throws {<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.originals = array<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.translated = try array.map(transform)<br class=""><br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var pointers = [UnsafePointer&lt;CType&gt;?]()<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for item in translated {<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pointers.append(UnsafePointer&lt;CType&gt;(item))<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pointers.append(nil)<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.pointers = pointers<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.pointer = UnsafePointer(self.pointers)<br class=""> &nbsp;&nbsp;&nbsp;}<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>