2014-06-07 11 views
25

Wie kann man die Daten in einem C-Array, wie beispielsweiseInteroperabilität von Swift-Arrays mit C?

float foo[1024]; 

, zwischen C und Swift-Funktionen, dem festen verwendet Größe Arrays, wie beispielsweise Feststellung durch

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

geben oder kopieren?

Antwort

18

Ich glaube nicht, dass dies leicht möglich ist. Genauso, wie Sie C-Style-Arrays für Parameter, die mit NSArray arbeiten, nicht verwenden können.

Alle C-Arrays in Swift werden durch eine UnsafePointer, z.B. 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 nacheinander 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

fand gerade eine bessere Lösung, das ist eigentlich das Kopieren vermeiden könnte.

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 
} 
+0

Sicherlich das Array mit unsicheren Zeigern m zu erreichen, ust kopieren Sie den Inhalt, wie es nicht weiß, wie lange es zugeordnet wird? – jhabbott

+0

@jhabbott Deshalb ist es "unsicher" :). Abhängig von der internen Repräsentation von Array <> muss es möglicherweise eine Kopie in einen zusammenhängenden Speicherbereich durchführen, wenn es nicht bereits in einem existiert, aber dies ist in der Praxis wahrscheinlich eher unwahrscheinlich/selten. – Ephemera

+2

Sieht aus wie '' '' mitUnsafePointerToElements''' entfernt wurde: https://developer.apple.com/library/mac/releasenotes/General/APIDiffsMacOSX10_10_3/modules/Swift.html – marchinram

7

Ab Beta 5, kann man nur & Array Das folgende Beispiel gibt 2 float Arrays an eine Funktion VDSP C verwenden passieren:

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)) 
+9

Wie wäre es mit einem Beispiel, das nicht funktioniert? Code nicht anzeigen? Es ist nicht ganz klar, welche Teile Sie demonstrieren möchten und welche nur Teil der C-API sind, die Sie verwenden. –

+0

@AbhiBeckert DSPSplitComplex ist ein Teil des Apple Accelerate-Frameworks, das eine C-API ist und ein gutes Beispiel ist. Es ist eine einfache Struktur zum Halten eines Vektors komplexer Zahlen. –

+0

Ab Swift 3 ist jetzt Array init: 'var myRealArray = [Float] (Wiederholung: 0.0, count: len)' –

8

Die withUnsafePointerToElements() Verfahren wurde entfernt, jetzt können Sie verwenden die withUnsafeBufferPointer() stattdessen verwenden baseAddress Verfahren in dem Block dem Punkt

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