如何从Swift中的索引开始将内存复制到UnsafeMutableRawPointer?

时间:2018-10-14 13:27:39

标签: swift pointers unsafe-pointers unsafemutablepointer

我知道如何使用以下命令将内存从数组复制到从索引0开始的UnsafeMutableRawPointer:

mutableRawPointer.copyMemory(from: bytes, byteCount: bytes.count * MemoryLayout<Float>.stride)

其中bytes是一个浮点数数组。

但是,我想从数组中复制一个可变的原始指针,该原始指针的索引可能不为零。

例如:

let array: [Float] = [1, 2, 3]

copyMemoryStartingAtIndex(to: myPointer, from: array, startIndexAtPointer: 2)

因此,如果指针为[0,0,0,0,0],它将变为[0,0,1,2,3]。

如何在Swift 4中实现这一目标?

1 个答案:

答案 0 :(得分:2)

您可以这样写:

//Caution: when T is not a `primitive` type, this code may cause severe memory issue
func copyMemoryStartingAtIndex<T>(to umrp: UnsafeMutableRawPointer, from arr: [T], startIndexAtPointer toIndex: Int) {
    let byteOffset = MemoryLayout<T>.stride * toIndex
    let byteCount = MemoryLayout<T>.stride * arr.count
    umrp.advanced(by: byteOffset).copyMemory(from: arr, byteCount: byteCount)
}

测试代码:

let size = MemoryLayout<Float>.stride * 5
let myPointer = UnsafeMutableRawPointer.allocate(byteCount: size, alignment: MemoryLayout<Float>.alignment)
defer {myPointer.deallocate()}

let uint8ptr = myPointer.initializeMemory(as: UInt8.self, repeating: 0, count: size)
defer {uint8ptr.deinitialize(count: size)}

func dump(_ urp: UnsafeRawPointer, _ size: Int) {
    let urbp = UnsafeRawBufferPointer(start: urp, count: size)
    print(urbp.map{String(format: "%02X", $0)}.joined(separator: " "))
}

let array: [Float] = [1, 2, 3]

dump(myPointer, size)
copyMemoryStartingAtIndex(to: myPointer, from: array, startIndexAtPointer: 2)
dump(myPointer, size)

输出:

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 80 3F 00 00 00 40 00 00 40 40

但是,我建议您考虑一下Hamish在评论中所说的话。