【问题标题】:How to cast UnsafeMutableRawPointer! to UnsafeMutablePointer<Float> in Swift 3.0 or newer?如何投射 UnsafeMutableRawPointer!到 Swift 3.0 或更高版本中的 UnsafeMutablePointer<Float> ?
【发布时间】:2018-10-12 11:15:27
【问题描述】:

我正在为我的 iOS 应用程序使用 Accelerate 库。几年前我在 Swift 2.0 中构建了这个应用程序,它运行良好。现在 Swift 更新到 3.0 和 4.0,我必须将大部分代码转换为当前语法。我已经运行了转换器,但仍然有一些语法错误。这是我最难解决的问题。我似乎找不到同样简洁的方法来修复它。

我为图像的基本算术运算创建了函数。 这是其中之一:

public func add(_ left: Image, right: Image) -> Image! {
    let results = Image.init(rows: left.size.rows, columns: left.size.columns, pixelSize: left.pixelSize)
    let leftOperand = UnsafeMutablePointer<Float>(left.buffer.data)
    let rightOperand = UnsafeMutablePointer<Float>(right.buffer.data)
    let destination = UnsafeMutablePointer<Float>(results.buffer.data)
    vDSP_vadd(leftOperand, 1, rightOperand, 1, destination, 1, UInt(left.lengthOfBuffer))
    return results
}

Image 类有一个字段buffer,它是一个vImage_Buffer,并且是这样定义的,

open class Image {

open var buffer: vImage_Buffer

....}

问题: 调用buffer.data 会返回UnsafeMutableRawPointer! 类型。 vDSP_add 函数的参数需要 UnsafeMutablePointer&lt;Float&gt;。我曾经能够立即将其转换为 UnsafeMutablePointer&lt;Float&gt; 对象。看起来初始化程序现在已弃用。因此,在 let leftOperand = UnsafeMutablePointer&lt;Float&gt;(left.buffer.data) 这样的代码上,我得到了这个错误

Cannot invoke initializer for type 'UnsafeMutablePointer<Float>' with an argument list of type '(UnsafeMutableRawPointer!)'.

我不知道我是否在这里忽略了一些非常简单的事情,但我仍然没有解决这个问题。但是,我正在寻找一种不需要使用循环手动复制每个元素的解决方案,因为该函数在应用程序中被非常频繁地调用。

只是一些可能有帮助的文档链接:

提前谢谢你!

【问题讨论】:

    标签: ios swift accelerate-framework unsafemutablepointer vimage


    【解决方案1】:

    我以前也有同样的问题。

    public func add(_ left: Image, right: Image) -> Image! {
    let results = Image.init(rows: left.size.rows, columns: left.size.columns, pixelSize: left.pixelSize)
    var leftOperand = Float(left.buffer.data)
    var rightOperand = Float(right.buffer.data)
    var destination = Float(results.buffer.data)
    vDSP_vadd(&leftOperand, 1, &rightOperand, 1, &destination, 1, UInt(left.lengthOfBuffer))
    return results
    }
    

    【讨论】:

    • 感谢您的建议! data 本身就是一个指针,因为它是 vImage_buffer 的一部分。尝试将其转换为 Float 时出错。似乎assumingMemoryBound(to:): 可能对我有用。
    【解决方案2】:

    使用assumingMemoryBound(to:):

    返回一个指向该指针所引用内存的类型化指针,假设内存已经绑定到指定类型。

    在你的情况下:

    let leftOp = left.buffer.data.assumingMemoryBound(to: Float.self)
    let rightOp = right.buffer.data.assumingMemoryBound(to: Float.self)
    // ...
    

    更多信息请参见UnsafeRawPointer Migration。

    【讨论】:

    • 我认为这可能会解决问题。至少,我没有收到编译器错误。修复其他错误后,我将立即提供更新。谢谢!
    • @KeenR.D.:有什么进展吗?如果您需要更多信息,请告诉我。
    • 感谢您的跟进。我完成了所有的转换。但是,我仍在试图找出这个代码签名问题。解决后,我会及时通知您。
    • 我已经让应用程序再次运行。您的解决方案有效!再次感谢您!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多