2014-06-07 220 views
25

如何可以一個Swift數組與C的互操作性?

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

通過或在C數組複製數據,如

float foo[1024]; 

,C和使用固定大小的數組夫特功能,如宣告之間?

回答

18

我不認爲這很容易。與使用NSArray的參數不能使用C風格的數組一樣。

Swift中的所有C數組都由UnsafePointer表示,例如, UnsafePointer<Float>。 Swift並不知道數據是一個數組。如果你想將它們轉換成一個Swift數組,你將創建一個新的對象並將它們逐個複製。

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) 

編輯

剛剛發現一個更好的解決方案,這樣做可能會避免複製。

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

當然,帶有不安全指針m的數組ust複製內容,因爲它不知道它將保持分配多久? – jhabbott

+0

@jhabbott這就是爲什麼它是「不安全的」:)。根據Array <>的內部表示形式,如果它不在一個存儲區中,它可能必須執行到連續存儲區的複製,但這在實踐中可能不太合適/不經常發生。 – Ephemera

+2

看起來像'''withUnsafePointerToElements'''被刪除:https://developer.apple.com/library/mac/releasenotes/General/APIDiffsMacOSX10_10_3/modules/Swift.html – marchinram

7

在Beta 5,一種可以只使用通過&陣列 下面的示例將2個浮陣列到VDSP C函數:

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

如何處理一個例子不顯示真實世界的代碼?目前還不清楚哪些部分是您正在嘗試演示的部分,哪些部分僅僅是您使用的C API的一部分。 –

+0

@AbhiBeckert DSPSplitComplex是Apple Accelerate框架的一部分,它是一個C API,是一個很好的例子。這是一個簡單的結構,用於保存複數的向量。 –

+0

從Swift 3開始,Array init現在是:'var myRealArray = [Float](重複:0.0,count:len)' –

8

除去withUnsafePointerToElements()方法,現在則可以使用代替withUnsafeBufferPointer(),並使用塊中的baseAddress方法實現該點

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