2016-11-02 2 views
0

struct 객체가 있습니다. 그리고 그 입력은 페이로드입니다. 이제는 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 업데이트 얻고있다.

구조체의 값을 변경하면 변경 가능한 데이터 값이 변경되지 않습니다 packet.

그리고 struct를 만든 후 패킷을 다시 만들려고하는 경우 충돌이 발생합니다.

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

답변

0

나는 XCode 8.1 Swift release notes에서 대답을 찾았습니다.

구조체 오브젝트를 변경 한 후 icmpPtr 버퍼 포인터로 다시 변경했습니다.

새 Data 객체를 만드는 대신 바이트를 교체하고 매력처럼 작동했습니다. 문서 당으로

:

엑스 코드 8.1 릴리스 노트 : https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Introduction.html 스위프트 섹션 : UnsafeRawBufferPointer 같은 값의 메모리 표현을 노출

새로운 withUnsafeBytes (:) 기능. 이 예 복사본 바이트 균질 한 배열로 이종 구조체 : 새로운 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 
} 
이다 바이트의 배열로 복사 예 정수 배열을
관련 문제