【问题标题】:Swift array as c function bufferSwift数组作为c函数缓冲区
【发布时间】:2016-06-14 10:22:27
【问题描述】:

我使用 swift 数组作为一个函数的输出缓冲区,该函数接受一个指针并填充它,如下所示:

var buffer : [Int32] = ...
tehFillFunc(UnsafeMutablePointer<Int32>(buffer))

这很好用,问题是编译器抱怨Variable 'buffer' was never mutated; consider changing to 'let' constant,我不想这样做,因为我很确定它在我的填充函数中发生了变异。

那么,有没有办法让它静音呢? (我可以做一些虚拟设置,但我更愿意正确地做)。

编辑:按照要求显示问题的完整示例代码(甚至不需要 c):

class ViewController: UIViewController {

    func fill(sth: UnsafeMutablePointer<Int32>) {
        sth[0] = 7
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        var array = [Int32].init(count: 10, repeatedValue: 0)
        fill(UnsafeMutablePointer<Int32>(array))
        print("\(array)")
    }
}

但是,解决方案已经发布。最简单的形式:

        fill(&array)

【问题讨论】:

  • 您的代码没有收到任何警告...
  • @MartinR 你说的对,不知道原来的C函数是怎么声明的。
  • 我假设void tehFillFunc(int *ptr);
  • 请用一个(小)自包含示例来说明问题。
  • 而且它似乎独立于 c/swift 作为函数的来源——只是 swift 声明形式很重要。

标签: arrays swift unsafemutablepointer


【解决方案1】:

通常您需要指定缓冲区大小。在这种情况下,我更喜欢以下解决方案:

let bufferSize = 1000
var buffer = [Int32](count: bufferSize, repeatedValue: 0)
tehFillFunc(&buffer)

【讨论】:

  • 嗯,这是最接近我需要的。看起来比我想象的要简单。
【解决方案2】:

Array 上有一个用于此目的的方法:

var buffer : [Int32] = ...

buffer.withUnsafeMutableBufferPointer {
    tehFillFunc($0.baseAddress)
}

我确保数组至少在withUnsafeMutableBufferPointer 返回之前是活动的。因为它需要一个inout 参数,所以缓冲区必须是var

【讨论】:

  • 前段时间我也是这么想的,但据我了解forums.developer.apple.com/thread/47085,单个函数调用不需要使用 withUnsafeMutableBufferPointer:"Swift 保证您以这种方式生成的指针将在函数调用期间保持有效。”
  • @MartinR 使用它的好处是它在变异情况下表现正确。例如,如果在buffer 上有一个didSet 观察者,它将在withUnsafeMutableBufferPointer 返回后正确调用一次。
  • 我明白了,这是一个很好的观点。 (但我仍然想知道编译器警告应该来自哪里,我无法重现它。)
  • @MartinR 我想知道这个函数是否真的被声明为tehFillFunc(const int *ptr);。另一个原因可能是过时的 Swift 版本......但我同意,如果 OP 能填补这些缺失的信息,那就太好了。
  • 在这种情况下,函数无法为指向的元素分配新值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-10
  • 2013-06-14
相关资源
最近更新 更多