21931


UnsafeMutablePointer型を何とか利用して  
構造体へのキャストもできるのではと考えたのですが、  
下記のようにした場合、  
(1)：構造体を初期化  
(2)：構造体のポインタを取得  
その後、(3)のようにしてみたもののmyptrにdataが設定されませんでした。  
何か良い方法はないのでしょうか。

# C言語のヘッダーファイル

[code]

    typedef struct {
    u_char test1;
    u_char test2;
    u_char test3[2];
    } TEST_STR;
    
[/code]

# swiftソース

[code]

    func casttest(data: NSData) -> UnsafeMutablePointer<TEST_STR> {
        var test = TEST_STR()   // (1)
        var myptr = withUnsafeMutablePointer(&test){$0}   // (2)
    
        // myptr.memory.test1　で参照できた（初期化しているので値は0）
    
        data.getByte(&myptr, length: sizeof(TEST_STR)    // (3)
    
        return myptr
    }
    
[/code]


CC BY-SA 3.0
2016-02-10T06:15:44.037
21929
2016-02-12T05:15:49.497
2016-02-12T05:15:49.497
12842
12842
question
swift
NSData内にあるバイトデータを構造体へのポインタとしてアクセスするには


すいません、下記の方法でキャストできました。  
他にも方法ある、こんなやり方じゃだめ！など意見もらえると嬉しいです。

[code]

    func casttest(data: NSData) -> UnsafeMutablePointer<TEST_STR> {
        var test = TEST_STR()   // (1)
        data.getByte(&test, length: sizeof(TEST_STR)    // (3)
        var myptr = withUnsafeMutablePointer(&test){$0}   // (2)
    
        return myptr
    }
    
[/code]


CC BY-SA 3.0
2016-02-10T06:24:46.033
21931
2016-02-10T06:24:46.033
12842
21929
answer


NSData内にあるバイトデータを構造体へのポインタとしてアクセスしたいのであれば、これだけでポインタを取得できます。

[code]

    func casttest(data: NSData) -> UnsafePointer<TEST_STR> {
        return UnsafePointer<TEST_STR>(data.bytes)
    }
    
[/code]

元の`data`がどこかの変数に保持されている限り解放された領域を指してしまう心配もありません。ただし、NSData内のデータは書き換え不可です。  
データの中身を書き換える可能性があるのならば、NSMutableDataにコピーしてから使うという手もあるのですが、必要な有効範囲を持った変数にさっさとコピーする方が楽でしょう。

[code]

    func mutablecasttest(data: NSData) {
        var test_str = casttest(data).memory
        //test_str(TEST_STR型になります)を使った処理...
    }
    
[/code]

できれば必要もないのにポインターを使うことは避けた方が良いのですが、どうしても使わなければいけない場合でも、解放された領域を指してしまっている宙ぶらりんポインターを作らないようにするべく、細心の注意を払ってください。また構造体の各メンバーのメモリ上における物理配置に依存したコードにすることの危険性についてはくれぐれも理解しておいてください。  
また、タイトルの「NSDataを構造体にキャスト」は不適切なので(NSData型はNSData型であり、構造体に型変換することはできません)、できればより適切なタイトルへの変更を考えてみてください。


CC BY-SA 3.0
2016-02-10T11:49:55.523
21946
2016-02-10T11:49:55.523
13972
21929
answer