2016-07-17 491 views
6

In Swift 3, la funzione C con la firma const char *f() è mappata su UnsafePointer<Int8>! f() durante l'importazione. È risultato può essere convertito in una stringa Swift come:Conversione di array di stringhe C in array di stringhe Swift

let swiftString = String(cString: f()) 

La domanda è, come un NULL terminato C array di stringhe C può essere mappato matrice Swift di stringhe?

La firma originale C:

const char **f() 

importati Swift firma:

UnsafeMutablePointer<UnsafePointer<Int8>?>! f() 

Swift array di stringhe:

let stringArray: [String] = ??? 

risposta

9

non esiste alcun metodo incorporato per quanto ne conoscere. Dovete iterare l'array puntatore restituito, la conversione di stringhe C a Swift String s, fino a quando un puntatore nil si trova:

if var ptr = f() { 
    var strings: [String] = [] 
    while let s = ptr.pointee { 
     strings.append(String(cString: s)) 
     ptr += 1 
    } 
    // Now p.pointee == nil. 

    print(strings) 
} 

Nota: Swift 3 utilizza puntatori opzionali per i puntatori che può essere nil. Nel tuo caso, f() restituisce un facoltativo facoltativo da scartare perché il file di intestazione non è "verificato": il compilatore non sa se la funzione può restituire NULL oppure no.

Utilizzando le "annotazioni nullability" si può prevedere che le informazioni al compilatore Swift:

const char * _Nullable * _Nullable f(void); 
// Imported to Swift as 
public func f() -> UnsafeMutablePointer<UnsafePointer<Int8>?>? 

se la funzione può restituire NULL, e

const char * _Nullable * _Nonnull f(void); 
// Imported to Swift as 
public func f() -> UnsafeMutablePointer<UnsafePointer<Int8>?> 

se f() è garantito per restituire un risultato non NULL.

Per ulteriori informazioni sulle annotazioni nullability, vedere ad esempio Nullability and Objective-C nel blog Swift.

+0

... e sono necessarie tecniche molto simili in altri linguaggi (incluso C++) che supportano un tipo "true" 'String'. Ognuno di questi "altri" linguaggi mantiene una "lunghezza" separata per ogni valore di stringa: non si basano su terminare null byte. Ma, tutti hanno metodi che sono specificamente progettati per affrontarli. (E, comunemente, mantengono un byte NULL noto alla fine del valore corrente che stanno memorizzando.) –

+0

... e ... * "meh" ... quando si tratta di computer digitali, io "mai dire 'mai.'" Se si tratta di un puntatore, potrebbe essere 'NULL'. Qualsiasi futuro * bug * in 'f()' che ha prodotto questo valore di ritorno sarebbe sbocciato in un bug * molto * sgradevole e difficile da localizzare, sprecando forse ore da ciò che era destinato a radere i microsecondi. Sono un programmatore molto * conservatore * ... –

+0

@MikeRobinson: Non ho aggiunto questa osservazione per "radere i microsecondi" ma per dirigere l'attenzione sulle annotazioni nullability. Ovviamente può essere discusso se il valore di ritorno di un'API che * è * documentato * per restituire un puntatore valido dovrebbe essere verificato su ogni chiamata, o se è considerato un errore di programmazione e dovrebbe bloccarsi prima. –