次のようなC配列のデータを渡すまたはコピーする方法
float foo[1024];
、CとSwiftの間で宣言されているような固定サイズの配列を使用する関数
let foo = Float[](count: 1024, repeatedValue: 0.0)
?
これは簡単にできるとは思いません。 NSArray
を使用するパラメーターにCスタイルの配列を使用できないのと同じ方法で。
Swift内のすべてのC配列はUnsafePointer
で表されます。例:UnsafePointer<Float>
。 Swiftは、データが配列であることを実際には認識していません。それらをSwift配列に変換する場合は、新しいオブジェクトを作成し、そこにあるアイテムを1つずつコピーします。
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
}
withUnsafePointerToElements()
メソッドが削除されました。代わりにwithUnsafeBufferPointer()
を使用し、ブロックでbaseAddress
メソッドを使用して目的を達成できます
let array: Array<Float> = [10.0, 50.0, 40.0]
array.withUnsafeBufferPointer { (cArray: UnsafePointer<Float>) -> () in
cArray.baseAddress
}
Beta 5以降は、pass&arrayのみを使用できます。次の例では、2つのfloat配列を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))
Apple何をするか見てみましょう:
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
}