54065


`Swift
4`から`C`のインターフェースで提供される`framework`を呼び出すにあたって、ファイルから読み込んだバイナリーデーターのポインターを関数に渡す必要があります。

バイナリーデーター自体はSwiftの

[code]

    let data: Data = try Data(contentsOf: dataURL)
    
[/code]

で読み込んだのは良いのですが、この`data`から`UnsafePointer<Int8>!`で、データー列の先頭アドレスを取得する一般的な方法はどの様になるのでしょうか？

  * `.withUnsafeBytes<Int8>`で愚直にコピーする
  * `Data`ではなく`NSData.bytes`をキャストする

が考えられますが、もっと素直に変換または取得出来るような気がするため、こうするといいよという方法がありましたらお教え下さい。


CC BY-SA 4.0
2019-01-07T21:31:48.533
51803
2019-04-11T09:23:01.093
2019-04-11T09:23:01.093
14745
14745
question
c swift4 swift5
SwiftからCのライブラリーを呼び出す際のDataについて


なぜ`withUnsafeBytes`を使う方法が「愚直」と感じられるのか理解に苦しみますが、Swiftの`Data`から内部のデータへのポインターを取得する唯一保証された方法が、`withUnsafeBytes`を使うことです。ただし「コピー」が必要かどうかは、場合によるのでなんとも言えませんが。

`NSData.bytes`を使う方法は、現在の実装では「多分」動くでしょうが、Swift的には保証されたものではありません。実際`NSData.bytes`はObjective-
C環境下でも最適化のレベル等によって動かないことがある(あった?)ことが報告されており、安全な方法とは言えません。

現在のSwiftの標準ライブラリは「確実に動作することを保証する範囲を狭めることにより、(将来の)最適化の余地を確保する」と言う方針で作られており、内部へのポインタが`withUnsafeBytes`のように引数のブロッックの範囲でしか有効にならない、というのもその一環です。標準ライブラリの設計思想を理解し、それに従ったコーディングをするというのが正しく聡明な方法でしょう。何をもって「素直」と言いたいのかわかりませんが、標準ライブラリの設計者が提供する機能を素直に利用するのが「もっとも素直な」方法でしょう。


CC BY-SA 4.0
2019-01-07T22:59:52.070
51804
2019-01-07T22:59:52.070
13972
51803
answer


`Swift`のwithUnsafeBytesには２種類のメソッド

[code]

    func withUnsafeBytes<ResultType, ContentType>(_ body: (UnsafePointer<ContentType>) throws -> ResultType) rethrows -> ResultType
    
[/code]

と

[code]

    func withUnsafeBytes<ResultType>(_ body: (UnsafeRawBufferPointer) throws -> ResultType) rethrows -> ResultType
    
[/code]

があり、前者はOS X
10.14.4で`Deprecate`になるよという警告が出る様になったので、今後の`Swift`で使い続けるためには後者のメソッドを使い、

[code]

    data.withUnsafeBytes({ (userDictionary: UnsafeRawBufferPointer) -> UnsafeMutableRawPointer? in
        if let ptr = userDictionary.baseAddress {
            // ptr にdataの先頭アドレスが入っているので、それをC関数への引数として処理を行う
        }// end optional binding check of userDictionary
    })// end withUnsafeBytes
    
[/code]

として上のソースの場合、変数`ptr`に代入された値を使う事で、OS X 10.14.4 & Xcode
10.2で警告なくコンパイル、実行できるようになりました。


CC BY-SA 4.0
2019-04-10T08:58:44.307
54065
2019-04-10T08:58:44.307
14745
51803
answer