Come passare un array di stringhe Swift a una funzione C prendendo un parametro char **

Sto cercando di interagire con una vecchia app per terminale C di Swift. Ho integrato con successo il codice sorgente e ho collegato le intestazioni da C a Swift. Il codice viene compilato e viene eseguito da Xcode 6.3 beta. Ho rinominato il punto di ingresso principale dell’app terminale per:

int initialize(int argc, char **argv); 

Tuttavia, sto lottando per passare gli argomenti da Swift a questa funzione C. La mia sfida è convertire gli argomenti nel formato giusto. Un tipico input da Swift potrebbe essere:

 let args = ["-c", "1.2.3.4", "-p", "8000"] 

Ho provato a fare scherzi con “cStringUsingEncoding (NSUTF8StringEncoding)” e “withUnsafePointer”, ma finora non ho avuto fortuna. Qualsiasi aiuto è molto apprezzato!

La funzione C.

 int initialize(int argc, char **argv); 

è mappato a Swift come

 func initialize(argc: Int32, argv: UnsafeMutablePointer>) -> Int32 

Questa è una ansible soluzione:

 let args = ["-c", "1.2.3.4", "-p", "8000"] // Create [UnsafeMutablePointer]: var cargs = args.map { strdup($0) } // Call C function: let result = initialize(Int32(args.count), &cargs) // Free the duplicated strings: for ptr in cargs { free(ptr) } 

Utilizza il fatto che in strdup($0) la stringa Swift $0 viene automaticamente convertita in una stringa C, come spiegato nel comportamento dei parametri della funzione String value to UnsafePointer .

Basandosi sulla risposta di Martin, se ti String.withCString farlo molto String.withCString , puoi avvolgere la parte dup / free in una funzione in uno stile simile a String.withCString :

 import Darwin func withCStrings  (strings: S, @noescape body: (UnsafeBufferPointer>) -> R) -> R { let cstrings = map(strings) { strdup($0) } + [nil] let result = cstrings.withUnsafeBufferPointer(body) for ptr in cstrings { free(ptr) } return result } let execvargs = ["/usr/bin/say"] + dropFirst(Process.arguments) let execvresult = withCStrings(execvargs) { execv($0[0], $0.baseAddress) }