swift 如何安全地调用DSPSplitComplex而不发出编译器警告

ebdffaop  于 2023-02-15  发布在  Swift
关注(0)|答案(1)|浏览(128)

我正在尝试调用函数DSPSplitComplex

var real = [Float](input_windowed)
var imaginary = [Float](repeating: 0.0, count: input_windowed.count)
        
var splitComplex = DSPSplitComplex(realp: &real, imagp: &imaginary)

但这会给我们一个警告

Cannot use inout expression here; argument 'realp' must be a pointer that outlives the call to 'init(realp:imagp:)'

所以在那之后我试着

var splitComplex = DSPSplitComplex(
    realp:  UnsafeMutablePointer(mutating: real),
    imagp:  UnsafeMutablePointer(mutating: imaginary) )

这就给出了警告:

Initialization of 'UnsafeMutablePointer<Float>' results in a dangling pointer

所以最后我试了这个:

var splitComplex =
    withUnsafeMutablePointer(to: &real) { realpPtr in
        withUnsafeMutablePointer(to: &imaginary) { imaginaryPtr in
            DSPSplitComplex(realp: realpPtr, imagp: imaginaryPtr)
    }
}

并且 that 会产生以下编译错误:

Cannot convert value of type 'UnsafeMutablePointer<[Float]>' to expected argument type 'UnsafeMutablePointer<Float>'

调用此函数(以及Accelerate框架中的类似函数)的正确方法是什么?

von4xj4u

von4xj4u1#

你已经很接近了,你只需要一个缓冲区指针而不是数组指针:

real.withUnsafeMutableBufferPointer { realp in
    imaginary.withUnsafeMutableBufferPointer { imagp in

        var splitComplex = DSPSplitComplex(realp: realp.baseAddress!, 
                                           imagp: imagp.baseAddress!)

        // ...
    }
}

注意调用的BufferPointer部分。
完整的例子请参见Apple的FFT sample
这种语法而不是你原来的方法的关键点在于它确保了realimaginary在指针的生命周期内继续存在。在你原来的代码中,数组可以在下一行被释放,使splitComplex持有悬空指针。

相关问题