2016-11-02 12 views
0

私は構造体オブジェクトを持っています。また、その入力はペイロードです。今私はpacketという名前のmutableDataを作成しています、そしてそれは変更可能なバイトはICMPHeader構造体を参照しています。NSMutableDataのバイトからUnsafeMutableRawPointerへの値がmutableDataの値を更新しない

struct ICMPHeader { 
    var type:UInt8 
    var code:UInt8 
    var checksum:UInt16 
    var identifier:UInt16 
    var sequenceNumber:UInt16 
}; 


func createPacket(payload:NSData) -> NSData(){ 
    var packet:NSMutableData? 
    var icmpPtr:ICMPHeader = ICMPHeader(type: 0, code: 0, checksum: 0, identifier: 0, sequenceNumber: 0) 
    packet = NSMutableData(length: Int(MemoryLayout<ICMPHeader>.size + payload.length)) 

    if packet != nil { 

     icmpPtr = packet!.mutableBytes.assumingMemoryBound(to: ICMPHeader.self).pointee 

     icmpPtr.type = type 
     icmpPtr.code = 0 
     icmpPtr.checksum = 0 
     icmpPtr.identifier = CFSwapInt16BigToHost(identifier) 
     icmpPtr.sequenceNumber = CFSwapInt16HostToBig(identifier) 
     memcpy(&icmpPtr + 1, payload.bytes, payload.length) 

     if (requiresChecksum) { 
      icmpPtr.checksum = in_cksum(packet!.bytes, bufferLen: packet!.length); 
     } 

    } 
    return packet 
} 

変更可能なバイトが正常に構造体へのバインドさばかりされており、値も構造体ICMPHeaderに更新されてきています。

structの値が変更されて、変更可能なデータの値が変更されないpacket

structを作成した後でパケットを再作成しようとすると、クラッシュしています。

package = NSMutableData(bytes: unsafeBitCast(icmpPtr, to: UnsafeMutableRawPointer.self), length: Int(MemoryLayout<ICMPHeader>.size + payload.length)) 

答えて

0

私はXCode 8.1 Swiftリリースノートで答えを見つけました。

構造体オブジェクトを変更した後、icmpPtr私はそれをバッファポインタに戻しました。

新しいDataオブジェクトを作成する代わりに、バイトを置き換えて魅力的に機能しました。ドキュメントを1として

XCodeの8.1リリースノート: https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Introduction.html スウィフト章:

新しいwithUnsafeBytes(の:)関数はUnsafeRawBufferPointerとして価値のインメモリ 表現を公開します。この例コピーバイトの均一な配列に 異種構造体:新しいArray.withUnsafeBytes方法はUnsafeRawBufferPointerとして、アレイの基礎となる バッファを露出

struct Header { 
var x: Int 
var y: Float 
} 

var header = Header(x: 0, y: 0.0) 
var byteBuffer = [UInt8]() 

withUnsafeBytes(of: &header) { 
    (bytes: UnsafeRawBufferPointer) in byteBuffer += bytes 
} 

let intArray = [1, 2, 3] 
var byteBuffer = [UInt8]() 

intArray.withUnsafeBytes { 
    (bytes: UnsafeRawBufferPointer) in byteBuffer += bytes 
} 

は、最終的な実装が

struct ICMPHeader { 
    var type:UInt8 
    var code:UInt8 
    var checksum:UInt16 
    var identifier:UInt16 
    var sequenceNumber:UInt16 
}; 


func createPacket(payload:NSData) -> NSData(){ 
    var packet:NSMutableData? 
    var icmpPtr:ICMPHeader = ICMPHeader(type: 0, code: 0, checksum: 0, identifier: 0, sequenceNumber: 0) 
    packet = NSMutableData(length: Int(MemoryLayout<ICMPHeader>.size + payload.length)) 

    if packet != nil { 

     icmpPtr = packet!.mutableBytes.assumingMemoryBound(to: ICMPHeader.self).pointee 

     icmpPtr.type = type 
     icmpPtr.code = 0 
     icmpPtr.checksum = 0 
     icmpPtr.identifier = CFSwapInt16BigToHost(identifier) 
     icmpPtr.sequenceNumber = CFSwapInt16HostToBig(identifier) 
     memcpy(&icmpPtr + 1, payload.bytes, payload.length) 

     if (requiresChecksum) { 
      icmpPtr.checksum = in_cksum(packet!.bytes, bufferLen: packet!.length); 
     } 

     var byteBuffer = [UInt8]() 
     withUnsafeBytes(of: &icmpPtr) { 
     (bytes: UnsafeRawBufferPointer) in byteBuffer += bytes 
     } 
     packet.replaceBytes(in: NSMakeRange(0, byteBuffer.count), withBytes: byteBuffer) 

    } 
    return packet 
} 
である:バイトの配列に、この例では、コピー 整数の配列を
関連する問題