Swift数组与C的互操作性?

hot*_*aw2 26 c objective-c swift

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

float foo[1024];
Run Code Online (Sandbox Code Playgroud)

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

let foo = Float[](count: 1024, repeatedValue: 0.0)
Run Code Online (Sandbox Code Playgroud)

Sul*_*han 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)
Run Code Online (Sandbox Code Playgroud)

编辑

刚刚找到了更好的解决方案,这实际上可以避免复制.

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
}
Run Code Online (Sandbox Code Playgroud)

  • 看起来像```withUnsafePointerToElements```被删除了:https://developer.apple.com/library/mac/releasenotes/General/APIDiffsMacOSX10_10_3/modules/Swift.html (2认同)

hot*_*aw2 9

从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))
Run Code Online (Sandbox Code Playgroud)

  • 一个没有显示真实世界代码的例子怎么样?目前尚不清楚哪些部分是您要演示的部分,哪些部分只是您正在使用的C API的一部分. (10认同)

小智 9

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

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