¿Recibiendo matriz multidimensional de C api, cómo manejar en Swift?

Utilizo una biblioteca C en mi aplicación Swift y no puedo determinar cómo get la matriz multidimensional que se supone que devolverá el método C.

Recibo esto de la API C:

struct resultArray { double *data; int size[2]; }; 

Dónde:

tamaño = el tamaño de la matriz, una matriz de dos elementos con el número de filas y el número de columnas

datos = los datos de la matriz

En swift puedo hacer lo siguiente para get el tamaño:

 let numRows = Int(results.size.0) let numColoumns = Int(results.size.1) 

Pero no entiendo cómo get la matriz para poder repetirla. Probé lo siguiente:

 let matrixResult = results.data.memory 

Esto parece devolver solo un valor doble porque matrixResult se convierte en un doble.

Entonces probé esto:

 let matrixResult = results.data 

Cuál hace que el resultado de la matriz sea:

 UnsafeMutablePointer<Double> 

Espero recibir una matriz como se especifica en la documentation de la biblioteca C. Entonces quiero repetir a través de esta matriz y get los valores de la primera fila y ponerla en una matriz Swift … ¿Alguien sabe lo que me falta aquí?

No hay ningún tipo de matriz en C. Suponiendo que los data son un puntero a los elementos de matriz contiguos almacenados como una matriz , copyría la primera fila en una matriz Swift con

 let firstRow = Array(UnsafeBufferPointer(start: results.data, count: numColumns)) 

y toda la "matriz" a una matriz Swift anidada con

 let matrix = (0 ..< numRows).map { row in Array(UnsafeBufferPointer(start: results.data + numColumns * row, count: numColumns)) } 

Alternativamente (y esto es similar a lo que sugirió Melifaro ), puede crear una matriz de apuntadores apuntando a las filas de la matriz:

 let matrix = (0 ..< numRows).map { row in UnsafeBufferPointer(start: results.data + numColumns * row, count: numColumns) } 

Esto todavía permite abordar elementos arbitrarios en una forma similar a una matriz

  let element = matrix[row][col] 

pero no copy los datos. Por supuesto, esto requiere que los datos de la matriz sean válidos durante todo el uso de la matrix , ya que Swift no gestiona la memory.

BTW, si trabaja con un gran set de datos, tiene sentido tratar los datos directamente en C-Structure, en lugar de duplicarlo en la estructura de datos Swift. Entonces, otra forma de hacer lo mismo:

 let (I, J) = res.size for i in 0..<I { for j in 0..<J { let v = res.data.advancedBy(Int(j + i * J)) let d: Double = v.memory print("[\(i), \(j)]: \(d)") } }