c arrays swift unsafe-pointers

Convertir un UnsafePointer con longitud a un tipo Swift Array



arrays unsafe-pointers (2)

Simplemente puede inicializar un Swift Array desde un UnsafeBufferPointer :

func convert(length: Int, data: UnsafePointer<Int8>) -> [Int8] { let buffer = UnsafeBufferPointer(start: data, count: length); return Array(buffer) }

Esto crea una matriz del tamaño necesario y copia los datos.

O como una función genérica:

func convert<T>(count: Int, data: UnsafePointer<T>) -> [T] { let buffer = UnsafeBufferPointer(start: data, count: count); return Array(buffer) }

donde length es la cantidad de elementos a los que apunta el puntero.

Si tiene un puntero UInt8 pero desea crear una matriz [T] partir de los datos apuntados a, esta es una posible solución:

// Swift 2: func convert<T>(length: Int, data: UnsafePointer<UInt8>, _: T.Type) -> [T] { let buffer = UnsafeBufferPointer<T>(start: UnsafePointer(data), count: length/strideof(T)); return Array(buffer) } // Swift 3: func convert<T>(length: Int, data: UnsafePointer<UInt8>, _: T.Type) -> [T] { let numItems = length/MemoryLayout<T>.stride let buffer = data.withMemoryRebound(to: T.self, capacity: numItems) { UnsafeBufferPointer(start: $0, count: numItems) } return Array(buffer) }

donde length ahora es el número de bytes . Ejemplo:

let arr = convert(12, data: ptr, Float.self)

crearía una matriz de 3 Float a partir de los 12 bytes a los que apunta ptr .

Estoy buscando las formas más sencillas de lograr una interoperabilidad C razonable en Swift, y mi bloque actual está convirtiendo un UnsafePointer<Int8> (que era un const char * ), en una matriz [Int8] .

Actualmente, tengo un algoritmo ingenuo que puede tomar un UnsafePointer y un número de bytes y lo convierte en una matriz, elemento por elemento:

func convert(length: Int, data: UnsafePointer<Int8>) { let buffer = UnsafeBufferPointer(start: data, count: length); var arr: [Int8] = [Int8]() for (var i = 0; i < length; i++) { arr.append(buffer[i]) } }

El bucle en sí puede acelerarse utilizando arr.reserveCapacity(length) , sin embargo, eso no elimina el problema del bucle en sí.

Soy consciente de esta pregunta SO que cubre cómo convertir UnsafePointer<Int8> a String , sin embargo, String es una bestia completamente diferente a [T] . ¿Existe una forma Swift conveniente de copiar bytes de longitud desde un UnsafePointer<T> a una [T] ? Prefiero los métodos Swift puros, sin pasar por NSData o similar. Si el algoritmo anterior es realmente la única forma de hacerlo, estoy feliz de seguir con eso.


extension NSData { public func convertToBytes() -> [UInt8] { let count = self.length / sizeof(UInt8) var bytesArray = [UInt8](count: count, repeatedValue: 0) self.getBytes(&bytesArray, length:count * sizeof(UInt8)) return bytesArray } }

Puede convertir los datos de la fila a bytes (Uint8)

Copia la extensión y úsala.