Swift数组与C的互操作性?

时间:2014-06-07 18:54:59

标签: objective-c c swift

如何传递或复制C数组中的数据,例如

float foo[1024];

,在使用固定大小数组的C和Swift函数之间,例如由

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

4 个答案:

答案 0 :(得分:19)

我认为这不容易。与使用C样式数组的方法相同,使用NSArray

的参数

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
}

答案 1 :(得分:9)

从Beta 5开始,人们可以使用pass&amp;数组 以下示例将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))

答案 2 :(得分:9)

已移除withUnsafePointerToElements()方法,现在您可以使用withUnsafeBufferPointer()代替,并使用块中的baseAddress方法来实现这一点

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

答案 3 :(得分:0)

让我们看看苹果在做什么:

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
}