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

Reply via email to