【问题标题】:Convert pointers from Swift 2 to Swift 3将指针从 Swift 2 转换为 Swift 3
【发布时间】:2017-02-21 20:31:12
【问题描述】:

如何将以下指针初始化从 Swift 2 转换为 Swift 3?

var values: [Double]
...
var valuesAsComplex : UnsafeMutablePointer<DSPDoubleComplex>?
values.withUnsafeBufferPointer { (resultPointer: UnsafeBufferPointer<Double>) -> Void in
    valuesAsComplex = UnsafeMutablePointer<DSPDoubleComplex>( resultPointer.baseAddress )
}

更新: 感谢您的所有回答。 像@Aderstedt 建议的那样永久重新绑定指针有效,但返回结果无效。有什么想法吗?

// Create result
var result = [Double](repeating: 0.0, count: N/2)
var resultAsComplex : UnsafeMutablePointer<DSPDoubleComplex>?
result.withUnsafeMutableBytes {
    resultAsComplex = $0.baseAddress?.bindMemory(to: DSPDoubleComplex.self, capacity: result.count)
}

// Do complex->real inverse FFT.
vDSP_fft_zripD(fftSetup!, &tempSplitComplex, 1, LOG_N, FFTDirection(FFT_INVERSE));

// This leaves result in packed format. Here we unpack it into a real vector.
vDSP_ztocD(&tempSplitComplex, 1, resultAsComplex!, 2, N2);

// Neither the forward nor inverse FFT does any scaling. Here we compensate for that.
var scale : Double = 0.5/Double(N);
vDSP_vsmulD(&result, 1, &scale, &result, 1, vDSP_Length(N));

return result

【问题讨论】:

  • 您能否提供一个独立的示例来说明问题?有输入、输出和预期输出?
  • 谢谢@martin-r !!!我想使用 iOS 相机创建一个心率监测器。我正在以 30fps 的速度从后置摄像头读取图像,并将图像的平均色调存储在一个数组中,为了消除噪声,我想使用 FFT 和 Accelerate 框架创建一个带通滤波器。我在 github github.com/codifilo/camera-heart-rate/blob/master/… 中分享了我的代码
  • 究竟是什么不起作用? – 请注意,寻求调试帮助的问题(“为什么这段代码不起作用?”)必须在问题本身中包含所需的行为、特定问题或错误以及重现它所需的最短代码。 没有明确问题陈述的问题对其他读者没有用处。另请参阅:如何创建 minimal reproducible example
  • 对不起,你是对的@martin-r。我创建了一个示例,其中包含重现问题所需的最短代码。运行以下示例,它有时会崩溃并显示消息“ malloc:*** 对象 0x101011a00 的错误:已释放对象的校验和不正确 - 对象可能在被释放后被修改。”在文件 FFT.swift 第 131 行中,示例只是尝试计算数组的 FFT 变换,它返回相同的值,但过滤了一些频率。项目在这里。 github.com/codifilo/fft-example/blob/master/FFTExample/…
  • 我在该存储库中只看到一个具有多个方法的 FFT 类。为了重现问题我必须运行的代码在哪里?

标签: swift pointers unsafe-pointers


【解决方案1】:

你必须“重新绑定”指针:

values.withUnsafeMutableBufferPointer {
    $0.baseAddress!.withMemoryRebound(to: DSPDoubleComplex.self, capacity: values.count/2) {
        valuesAsComplex in

        // ...

    }
}

在闭包valuesAsComplex 里面是一个 UnsafeMutablePointer&lt;DSPDoubleComplex&gt; 可以传递给DSP 职能。

您必须将指向元素存储的指针传递给 正如documentation 明确指出的那样,在关闭之外:

指针参数仅在闭包执行期间有效。

这可能是偶然的,但不能保证在 执行闭包,元素存储仍然相同 内存地址(或者数组甚至存在,因为指针 不是确保存储生命周期的强参考)。


在你的情况下

    tempSplitComplex = DSPDoubleSplitComplex(realp: &mag, imagp: &phase)
    vDSP_ztocD(&tempSplitComplex, 1, &tempComplex, 2, N2);

    tempComplex.withUnsafeMutableBufferPointer {
        $0.baseAddress!.withMemoryRebound(to: Double.self, capacity: values.count * 2) {
            complexAsDouble in

            vDSP_rectD(complexAsDouble, 2, complexAsDouble, 2, N2);
        }
    }

    vDSP_ctozD(&tempComplex, 2, &tempSplitComplex, 1, N2);

    var result = [Double](repeating: 0.0, count: N/2)

    result.withUnsafeMutableBufferPointer {
        $0.baseAddress!.withMemoryRebound(to: DSPDoubleComplex.self, capacity: result.count/2) {
            resultAsComplex in

            vDSP_ztocD(&tempSplitComplex, 1, resultAsComplex, 2, N2);

        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    相关资源
    最近更新 更多