web-dev-qa-db-de.com

Interoperabilität von Swift-Arrays mit C?

Wie kann man die Daten in einem C-Array übergeben oder kopieren, z

float foo[1024];

zwischen C- und Swift-Funktionen, die Arrays mit fester Größe verwenden, wie z. B. deklariert von

let foo = Float[](count: 1024, repeatedValue: 0.0)

?

26
hotpaw2

Ich glaube nicht, dass das leicht möglich ist. Auf dieselbe Weise können Sie keine Arrays im C-Stil für Parameter verwenden, die mit NSArrayarbeiten.

Alle C-Arrays in Swift werden durch UnsafePointerdargestellt, z. UnsafePointer<Float>. Swift weiß nicht wirklich, dass die Daten ein Array sind. Wenn Sie sie in ein Swift-Array konvertieren möchten, müssen Sie ein neues Objekt erstellen und die Elemente dort einzeln kopieren.

let array: Array<Float> = [10.0, 50.0, 40.0]

// I am not sure if alloc(array.count) or alloc(array.count * sizeof(Float))
var cArray: UnsafePointer<Float> = UnsafePointer<Float>.alloc(array.count)
cArray.initializeFrom(array)

cArray.dealloc(array.count)

Bearbeiten

Gerade eine bessere Lösung gefunden, könnte das Kopieren tatsächlich vermeiden.

let array: Array<Float> = [10.0, 50.0, 40.0]

// .withUnsafePointerToElements in Swift 2.x
array.withUnsafeBufferPointer() { (cArray: UnsafePointer<Float>) -> () in
    // do something with the C array
}
19
Sulthan

Die withUnsafePointerToElements()-Methode wurde entfernt. Jetzt können Sie stattdessen die withUnsafeBufferPointer() verwenden und die baseAddress-Methode im Block verwenden, um den Punkt zu erreichen

let array: Array<Float> = [10.0, 50.0, 40.0]
array.withUnsafeBufferPointer { (cArray: UnsafePointer<Float>) -> () in
    cArray.baseAddress
}
8
yglixm

Ab Beta 5 kann man nur pass & array Verwenden. Das folgende Beispiel übergibt 2 Float-Arrays an eine vDSP-C-Funktion:

let logLen = 10
let len = Int(pow(2.0, Double(logLen)))
let setup : COpaquePointer = vDSP_create_fftsetup(vDSP_Length(logLen), FFTRadix(kFFTRadix2))

var myRealArray = [Float](count: len, repeatedValue: 0.0)
var myImagArray = [Float](count: len, repeatedValue: 0.0)
var cplxData = DSPSplitComplex(realp: &myRealArray, imagp: &myImagArray)

vDSP_fft_Zip(setup, &cplxData, 1, vDSP_Length(logLen),FFTDirection(kFFTDirection_Forward))
8
hotpaw2

mal sehen, was Apple macht:

public struct float4 {

    public var x: Float

    public var y: Float

    public var z: Float

    public var w: Float

    /// Initialize to the zero vector.
    public init()

    /// Initialize a vector with the specified elements.
    public init(_ x: Float, _ y: Float, _ z: Float, _ w: Float)

    /// Initialize a vector with the specified elements.
    public init(x: Float, y: Float, z: Float, w: Float)

    /// Initialize to a vector with all elements equal to `scalar`.
    public init(_ scalar: Float)

    /// Initialize to a vector with elements taken from `array`.
    ///
    /// - Precondition: `array` must have exactly four elements.
    public init(_ array: [Float])

    /// Access individual elements of the vector via subscript.
    public subscript(index: Int) -> Float
}
0
lbsweek