2016-07-17 35 views
6

Swift 3では、Cの関数const char *f()はインポート時にUnsafePointer<Int8>! f()にマップされます。C文字列の配列をSwift文字列に変換

let swiftString = String(cString: f()) 

質問は、NULLが終了する方法をC文字列のC配列が文字列のスウィフト配列にマッピングすることができている:それは、結果としてスウィフト文字列に変換することができますか?

原C署名:

const char **f() 

インポートスウィフト署名:

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

ストリングのスウィフト配列:

let stringArray: [String] = ??? 

答えて

9

ない組み込み方法は限りIとして存在しません知っている。 nilポインタが見つかるまでは、スイフトString SにCの文字列を変換し、返されたポインタ配列を反復する必要が :

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) 
} 

備考:スウィフト3であることができるポインタのための任意のポインタを使用しnil。 は、 ヘッダーファイルが「監査」されていないため、暗黙的にアンラップされたオプションを返します。 関数がNULLを返すかどうかはコンパイラが認識しません。 f()を返すことが保証されている場合機能はNULL、および

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

を返すことができる場合

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

:あなたはスウィフト、コンパイラにその情報 を提供することができ、「NULL可能注釈」を使用して

NULL以外の結果。

null可否アノテーションの詳細については、Swiftブログの Nullability and Objective-Cを参照してください。

+0

... "真の"文字列型をサポートする他の言語(C++を含む)では非常によく似た手法が必要です。これらの「他の」言語はそれぞれ、文字列値ごとに別々の「長さ」を保持しています。ヌルバイトの終了には依存しません。しかし、彼らはすべてそれらを扱うように特別に設計された方法を持っています。 (そして、一般的には、それらは、それらが格納している現在の値の最後に既知のNULLバイトを保持しています。) –

+0

... and ... * "meh" ...デジタルコンピュータに関してはいつでも"決して '決して言わないでください。'"それがポインタなら、それは 'NULL'かもしれません。この戻り値を生成する 'f()'の将来のバグ*は、非常に厄介で見つけにくいバグになり、マイクロ秒を節約しようとしていた時から何時間も無駄になります。私は非常に*保守的なコーダーです... –

+0

@MikeRobinson:私は「マイクロ秒を短くする」という言葉を追加しませんでしたが、NULL可能性の注釈に注意を向けました。もちろん、有効なポインタを返すために*文書化された* APIの戻り値が各呼び出しでチェックされるべきか、それがプログラミングエラーとみなされ、早期にクラッシュするかどうかについて議論することができます。 –

関連する問題