将具有长度的 UnsafePointer 转换为 Swift 数组类型

标签 c arrays swift unsafe-pointers

我正在寻找在 Swift 中实现合理的 C 互操作性的最简单方法,我当前的 block 正在转换 UnsafePointer<Int8> (这是一个 const char * ),变成一个 [Int8]数组。

目前,我有一个朴素的算法,可以采用 UnsafePointer和一些字节并将其逐个元素转换为数组:

func convert(length: Int, data: UnsafePointer<Int8>) {

    let buffer = UnsafeBufferPointer(start: data, count: length);
    var arr: [Int8] = [Int8]()
    for (var i = 0; i < length; i++) {
        arr.append(buffer[i])
    }
}

循环本身可以通过使用 arr.reserveCapacity(length) 来加速,但这并没有消除循环本身的问题。

我知道 this SO question其中包括如何转换 UnsafePointer<Int8>String , 然而 String[T]完全不同.是否有一种方便的 Swift 方法从 UnsafePointer<T> 中复制长度字节?进入[T] ?我更喜欢纯 Swift 方法,而不通过 NSData或类似的。如果上述算法真的是唯一的方法,我很乐意坚持下去。

最佳答案

您可以简单地从 UnsafeBufferPointer 初始化 Swift Array:

func convert(length: Int, data: UnsafePointer<Int8>) -> [Int8] {

    let buffer = UnsafeBufferPointer(start: data, count: length);
    return Array(buffer)
}

这将创建一个所需大小的数组并复制数据。

或者作为通用函数:

func convert<T>(count: Int, data: UnsafePointer<T>) -> [T] {

    let buffer = UnsafeBufferPointer(start: data, count: count);
    return Array(buffer) 
}

其中 length 是指针指向的 items 的数量。

如果您有一个 UInt8 指针,但想从中创建一个 [T] 数组 指向的数据,那么这是一个可能的解决方案:

// Swift 2:
func convert<T>(length: Int, data: UnsafePointer<UInt8>, _: T.Type) -> [T] {

    let buffer = UnsafeBufferPointer<T>(start: UnsafePointer(data), count: length/strideof(T));
    return Array(buffer) 
}

// Swift 3:
func convert<T>(length: Int, data: UnsafePointer<UInt8>, _: T.Type) -> [T] {
    let numItems = length/MemoryLayout<T>.stride
    let buffer = data.withMemoryRebound(to: T.self, capacity: numItems) {
        UnsafeBufferPointer(start: $0, count: numItems)
    }
    return Array(buffer) 
}

length 现在是 bytes 的数量。示例:

let arr  = convert(12, data: ptr, Float.self)

将从 ptr 指向的 12 个字节创建一个包含 3 个 Float 的数组。

关于将具有长度的 UnsafePointer 转换为 Swift 数组类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32606989/

相关文章:

c - 输入不足

c++ - mmap 文件,其中包含一个不受该文件支持的额外页面

javascript - 如何摆脱Javascript字符串中动态指定位置后的所有字符

ios - 无法关闭从闭包中调用的 UIAlertController

c - 在 C 中访问多维字符串数组的元素

Javascript将对象数组累积到对象数组

python - 是否可以对访问 numpy 数组中不同元素的函数进行矢量化?

ios - 从 Realm 结果转换为数组产生空对象

ios - 尝试在 Swift 中使用警报操作切换到另一个 View Controller

c - Arduino Due Sam3X8E 访问定时器值