Swift: cómo añadir offset a memcpy (…)

¿Cómo agregar desplazamiento para array para memcpy (…) invocación?

Tengo un array de String :

 var source = ["a","b","c","d"] var dest = [String](count:n, repeatedValue: "") memcpy(&dest, source, UInt(2 * sizeof(String)) 

Esta copy ["a", "b"] para dest. Es obvio. ¿Cómo puedo copyr ["b", "c"]?

No use memcpy u otros operadores de "C" de bajo nivel en los objects. Eso no funcionará por muchos motivos.

Utiliza el operador de sector:

 var source = ["a","b","c","d"] var dest = Array(source[1...2]) println("dest: \(dest)") 

salida:

dest: [b, c]

Unicode se maneja correctamente:

 var source = ["🇪🇸", "😂", "a","b","c","d"] var dest = Array(source[1...2]) println("dest: \(dest)") 

salida:

dest: [😂, a]

En primer lugar, hay algo que ninguno de los escritores parece haber entendido: una matriz de objects (aquí las instancias de String) no almacenan el contenido sino una reference a este object. Por lo tanto, UTF-8, UTF-16, lo que sea que no tenga nada que ver con eso. Lo que realmente contiene la matriz de respaldo son pointers (es decir, direcciones == numbers integers sin signo). Aparte de eso, a less que una matriz en swift sea una matriz real en la memory, no debería usar memcpy en ella, ¡más aún si está respaldada por una NSArray!

Sin embargo, para responder a la pregunta original que parece funcionar a la perfección y me hace pensar que en este caso Swift Array es una zona contigua de memory aquí es lo que debes hacer:

fuente y dest son pointers a las zonas de memory contiguas: el primer object está en la dirección base, el segundo @ + tamaño de (tipo), el nésimo elemento en @ + (n-1) * tamaño de (tipo).

Todo lo que tiene que hacer es especificar el desplazamiento de escritura para dest, en su caso particular 0, y el desplazamiento en origen, en su caso 1.

Todavía soy nuevo en Swift y el uso de methods con "inseguro" en el nombre todavía me preocupa, pero estoy bastante seguro de que se trata de una técnica útil para llamar a memcpy () y especificar un desplazamiento para el destino y / o la fuente dirección. Pero esto solo funciona para matrices de bytes, es decir, [UInt8]. Definitivamente no para cadenas, como lo explica @zaph.

 public class SystemMisc { /// Wrapper for the memcpy() method that allows specification of an offset for the destination /// and/or the source addresses. /// /// This version for when destination is a normal Swift byte array. /// /// - Parameters: /// - destPointer: Address for destination byte array, typically Swift [UInt8]. /// - destOffset: Offset to be added to the destination address, may be zero. /// - sourcePointer: Address for source byte array, typically Swift [UInt8]. /// - sourceOffset: Offset to be added to the source address, may be zero. /// - byteLength: Number of bytes to be copied. public static func memoryCopy(_ destPointer : UnsafeRawPointer, _ destOffset : Int, _ sourcePointer : UnsafeRawPointer, _ sourceOffset : Int, _ byteLength : Int) { memoryCopy(UnsafeMutableRawPointer(mutating: destPointer), destOffset, sourcePointer, sourceOffset, byteLength) } /// Wrapper for the memcpy() method that allows specification of an offset for the destination /// and/or the source addresses. /// /// This version for when destination address is already available as an UnsafeMutableRawPointer, /// for example if caller has used UnsafeMutableRawPointer() to create it or is working with /// unmanaged memory. The destPointer argument may also be a converted pointer, as done by the /// above wrapper method. /// /// - Parameters: /// - destPointer: Address for destination byte array, see above notes. /// - destOffset: Offset to be added to the destination address, may be zero. /// - sourcePointer: Address for source byte array, typically Swift [UInt8]. /// - sourceOffset: Offset to be added to the source address, may be zero. /// - byteLength: Number of bytes to be copied. public static func memoryCopy(_ destPointer : UnsafeMutableRawPointer, _ destOffset : Int, _ sourcePointer : UnsafeRawPointer, _ sourceOffset : Int, _ byteLength : Int) { memcpy(destPointer.advanced(by: destOffset), sourcePointer.advanced(by: sourceOffset), byteLength) } } 

Y aquí hay un código de testing:

  // Test the memoryCopy() method, using extra UnsafeMutableRawPointer conversion let destArray1 : [UInt8] = [ 0, 1, 2, 3 ] // Note - doesn't need to be var let sourceArray1 : [UInt8] = [ 42, 43, 44, 45 ] SystemMisc.memoryCopy(destArray1, 1, sourceArray1, 1, 2) assert(destArray1[0] == 0 && destArray1[1] == 43 && destArray1[2] == 44 && destArray1[3] == 3) // Test the memoryCopy() method, providing UnsafeMutableRawPointer for destination var destArray2 : [UInt8] = [ 0, 1, 2, 3 ] let sourceArray2 : [UInt8] = [ 42, 43, 44, 45 ] let destArray2Pointer = UnsafeMutableRawPointer(&destArray2) SystemMisc.memoryCopy(destArray2Pointer, 1, sourceArray2, 1, 2) assert(destArray2[0] == 0 && destArray2[1] == 43 && destArray2[2] == 44 && destArray2[3] == 3)