Thanks! At least it’s good to know there wasn’t something trivial I was missing.
-Kenny > On Aug 18, 2016, at 2:33 PM, Jordan Rose <jordan_r...@apple.com> wrote: > > Here's how we do it for internal testing purposes: withArrayOfCStrings. 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 >> <swift-users@swift.org> 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 >> swift-users@swift.org >> https://lists.swift.org/mailman/listinfo/swift-users > _______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users