【问题标题】:Working with UnsafeMutablePointer array使用 UnsafeMutablePointer 数组
【发布时间】:2016-05-20 12:54:31
【问题描述】:

我正在尝试使用 Brad Larson 出色的 GPUImage 框架,并且正在努力处理 GPUImageHarrisCornerDetectionFilter 返回的cornerArray。

角在UnsafeMutablePointer 中以GLFloat 数组的形式返回 - 我想将其转换为CGPoint 数组

我已经尝试为内存分配空间

var cornerPointer = UnsafeMutablePointer<GLfloat>.alloc(Int(cornersDetected) * 2)

但数据似乎没有任何意义 - 无论是零还是 1E-32

我找到了看似完美的答案how to loop through elements of array of <UnsafeMutablePointer> in Swift 并尝试了

filter.cornersDetectedBlock = {(cornerArray:UnsafeMutablePointer<GLfloat>, cornersDetected:UInt, frameTime:CMTime) in
        crosshairGenerator.renderCrosshairsFromArray(cornerArray, count:cornersDetected, frameTime:frameTime)

    for floatData in UnsafeBufferPointer(start: cornerArray, count: cornersDetected)
    {
        println("\(floatData)")
    }

但编译器不喜欢 UnsafeBufferPointer - 所以我将其更改为 UnsafeMutablePointer,但它不喜欢参数列表。

我确信这很好而且很简单,而且听起来像是其他人必须必须做的事情 - 那么解决方案是什么?

【问题讨论】:

  • 你看到中的小写f了吗?错字可能是失败的原因。
  • 一开始没有!但我做到了:-)

标签: ios swift gpuimage unsafe-pointers


【解决方案1】:

从 C 转换而来的 UnsafeMutablePointer&lt;GLfloat&gt; 类型可以通过下标访问其元素,就像普通数组一样。为了实现将这些转换为 CGPoints 的目标,我将使用以下代码:

filter.cornersDetectedBlock = { (cornerArray:UnsafeMutablePointer<GLfloat>, cornersDetected:UInt, frameTime:CMTime) in
    var points = [CGPoint]()
    for index in 0..<Int(cornersDetected) {
       points.append(CGPoint(x:CGFloat(cornerArray[index * 2]), y:CGFloat(cornerArray[(index * 2) + 1])))
    }
    // Do something with these points
}

支持cornerArray 的内存在触发回调之前立即分配,并在触发之后立即释放。除非您像我在上面所做的那样在块的中间复制这些值,否则恐怕您会让自己面对一些讨厌的错误。无论如何,此时转换为正确的格式也更​​容易。

【讨论】:

  • 太棒了——我就是这样做的:-)
  • 见“UnsafeBufferPointer”解决方案,应该快很多倍。
【解决方案2】:

我找到了一个解决方案——而且很简单。答案就在这里https://gist.github.com/kirsteins/6d6e96380db677169831

var dataArray = Array(UnsafeBufferPointer(start: cornerArray, count: Int(cornersDetected) * 2))

【讨论】:

  • 我不完全确定在这种情况下这是安全的。 cornerArray 的后备内存在调用此块之前手动分配,并在之后立即手动释放。我相信如果你这样做,你会遇到内存损坏错误。我提供了一个答案,展示了如何安全地将这些值复制到您想要的格式中。
  • 这是最快的方法并且是安全的,根据 Apple 的文档:“但是,使用 UnsafeBufferPointer 实例初始化另一个集合会将实例从引用的内存复制到新集合中”
【解决方案3】:

试试这个:

     var cornerPointer = UnsafeMutablePointer<GLfloat>.alloc(Int(cornersDetected) * 2)

    filter.cornersDetectedBlock = {(cornerArray:UnsafeMutablePointer<GLfloat>, cornersDetected:UInt, frameTime:CMTime) in
        crosshairGenerator.renderCrosshairsFromArray(cornerArray, count:cornersDetected, frameTime:frameTime)

    for i in 0...cornersDetected
    {
        print("\(cornerPointer[i])")
    }

【讨论】:

  • 我不确定我是否理解这一点。 cornersDetected 仅在闭包内定义,因此不能在cornersDetectedBlock 之前使用它。除了代码的错误顺序之外,我没有看到任何与我已有的不同的地方
猜你喜欢
  • 2019-12-08
  • 2016-01-19
  • 1970-01-01
  • 2021-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多