Как скопировать память в UnsafeMutableRawPointer, начиная с индекса в Swift?

Я знаю, как скопировать память из массива в UnsafeMutableRawPointer, начиная с индекса 0, используя:

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

где bytes — массив чисел с плавающей запятой.

Однако я хотел бы скопировать из моего массива в изменяемый необработанный указатель, начиная с индекса, который может быть не равен нулю.

Eg.:

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?


person BroccoliFinancials    schedule 14.10.2018    source источник
comment
(mutableRawPointer + byteOffset).copyMemory(...)? Хотя я бы настоятельно рекомендовал использовать типизированный указатель, если вы знаете, что базовая память привязана к данному типу.   -  person Hamish    schedule 14.10.2018
comment
На самом деле это указатель, заданный функцией contents из MTLBuffer.   -  person BroccoliFinancials    schedule 14.10.2018


Ответы (1)


Вы можете написать что-то вроде этого:

//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

Но я рекомендую вам подумать о том, что говорит Хэмиш в комментарии.

person OOPer    schedule 14.10.2018