【问题标题】:NSMutableData's bytes to UnsafeMutableRawPointer not updating the value of mutableDataNSMutableData 到 UnsafeMutableRawPointer 的字节不更新 mutableData 的值
【发布时间】:2016-11-02 18:09:57
【问题描述】:

我有一个结构对象。还有一个方法,它的输入是有效载荷。现在我正在创建一个名为 packet 的 mutableData,它的可变字节指的是 ICMPHeader 结构。

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 的值。

如果我在创建结构后尝试重新创建数据包,那么它就会崩溃。

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

【问题讨论】:

    标签: ios swift3 icmp unsafe-pointers unsafemutablepointer


    【解决方案1】:

    我在 XCode 8.1 Swift 发行说明中找到了答案。

    在 struct object icmpPtr 进行更改后,我已将其更改回缓冲区指针。

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

    所以我没有创建新的 Data 对象,而是替换了字节,它就像一个魅力。

    根据文档:

    XCode 8.1 发行说明: https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Introduction.html 快速部分:

    一个新的 withUnsafeBytes(of:) 函数暴露了一个值的内存 表示为 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
    }
    

    一个新的 Array.withUnsafeBytes 方法公开了一个数组的底层 缓冲区作为 UnsafeRawBufferPointer。这个例子复制了一个数组 整数转换为字节数组:

    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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多