在Swift 5中将void *参数传递给c函数时,不推荐使用'withUnsafeBytes'警告

时间:2019-03-31 10:31:56

标签: c swift unsafe-pointers

我有一个使用外部提供的c库快速解析FIT文件的库。解析函数将void * data作为参数。 为了调用该函数,我正在使用data.withUnsafeBytes( { (ptr: UnsafePointer<UInt8>) in ...}转换数据以建立c函数的参数,并且可以正常工作。

将Xcode升级到Swift 5之后,我现在收到了已弃用的警告

'withUnsafeBytes'已过时:改为使用withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R

我不知道如何解决代码以删除不推荐使用的警告。该代码运行良好,并且没有迅速发出警告4

我试图将闭包中的参数更改为UnsafeRawBufferPointer而不是UnsafePointer,但这导致调用函数Cannot convert 'UnsafeRawBufferPointer' to expected argument type 'UnsafeRawPointer?'

时出错

这是一个快速显示问题的小文件:

import Foundation

// Create sample data (Typically would be read from a file
let data = Data(repeating: 1, count: 10)

data.withUnsafeBytes( { (ptr : UnsafePointer<UInt8>) in
    // call the c function with the void* argument
    let value = readFITfile(ptr)
    print( value )
})

还有一个示例c函数

unsigned readFITfile(const void * data){
    //Silly example to show it works, just returning the value of pointer as int
    //Typically would parse the data and return a structure
    return (unsigned)data;
}

我在这里https://github.com/roznet/swift2c用上面的代码保存了一个小型仓库,在这里https://github.com/roznet/fit-sdk-swift

有文件的完整解析项目。

2 个答案:

答案 0 :(得分:4)

您必须将闭包参数更改为UnsafeRawBufferPointer,然后采用其baseAdress(这是UnsafeRawPointer?,与C中void *的Swift等效):

data.withUnsafeBytes( { (ptr : UnsafeRawBufferPointer) in
    let value = readFITfile(ptr.baseAddress)
    // ...
})

Swift编译器还可以自动推断闭包参数类型:

data.withUnsafeBytes( { ptr in
    let value = readFITfile(ptr.baseAddress)
    // ...
})

有关此问题的更多信息,请参见Swift论坛中的withUnsafeBytes Data API confusion

答案 1 :(得分:1)

要立即获取UnsafePointer,您应该执行类似的操作

data.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) in
    if let ptrAddress = ptr.baseAddress, ptr.count > 0 {
        let pointer = ptrAddress.assumingMemoryBound(to: UInt8.self) // here you got UnsafePointer<UInt8>
        let value = readFITfile(ptr)
        print( value )
    } else {
        // Here you should provide some error handling if you want ofc
    }
}