Here's how we do it for internal testing purposes: withArrayOfCStrings <https://github.com/apple/swift/blob/dfc3933a05264c0c19f7cd43ea0dca351f53ed48/stdlib/private/SwiftPrivate/SwiftPrivate.swift#L68>. The callback is great because you don't have to worry about lifetimes.
Jordan > On Aug 18, 2016, at 13:04, Kenny Leung via swift-users > <[email protected]> wrote: > > Hi All. > > 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. > > 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: > > public extension Array { > public func cStringArray() throws -> ArrayBridge<Element,CChar> { > return try ArrayBridge<Element,CChar>(array:self) { > guard let item = $0 as? String, > let translated = item.cString(using: .utf8) else { > throw hexdreamsCocoa.Errors.InvalidArgumentError > } > return translated > } > } > } > > /* > We need to have this intermediate object around to hold on to the translated > objects, otherwise they will go away. > The UnsafePointer won't hold on to the objects that it's pointing to. > */ > public struct ArrayBridge<SwiftType,CType> { > > let originals :[SwiftType] > let translated :[[CType]] > let pointers :[UnsafePointer<CType>?] > public let pointer :UnsafePointer<UnsafePointer<CType>?> > > init(array :[SwiftType], transform: (SwiftType) throws -> [CType]) throws { > self.originals = array > self.translated = try array.map(transform) > > var pointers = [UnsafePointer<CType>?]() > for item in translated { > pointers.append(UnsafePointer<CType>(item)) > } > pointers.append(nil) > self.pointers = pointers > self.pointer = UnsafePointer(self.pointers) > } > } > > And then to use it you would do something like > > try stringArray.cStringArray().pointer > > 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. > > Thanks! > > -Kenny > > > > _______________________________________________ > swift-users mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________ swift-users mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-users
