将Swift String数组转换为c char **

时间:2017-12-20 17:39:36

标签: c arrays swift

我正在从Swift 4调用一个C库,我将[String]转换为const char *[]时遇到了麻烦。

C API定义了这个方法:

int getDREFs(const char* drefs[], unsigned char count);

在Swift中暴露为

public func getDREFs(_ drefs: UnsafeMutablePointer<UnsafePointer<Int8>?>!, _ count: UInt8) -> Int32

我正在尝试编写的Swift包装器如下

public func get(drefs: [String]) throws {

    var cDrefs = [UnsafePointer<Int8>]()
    for dref in drefs {
        cDrefs.append(dref.cString(using: .utf8)!)
    }
    let pDrefs = UnsafeMutablePointer<UnsafePointer<Int8>>(&cDrefs)
    getDREFFs(pDrefs, drefs.count)

}

但我得到的错误是

Cannot convert value of type 'UnsafeMutablePointer<UnsafePointer<Int8>>' to expected argument type 'UnsafeMutablePointer<UnsafePointer<Int8>?>!'

我错过了什么?

1 个答案:

答案 0 :(得分:1)

getDREFSs需要一个指向可选 Int8指针数组的指针。 第二个参数也必须转换为UInt8

所以这会编译:

public func get(drefs: [String]) -> Int {
    var cDrefs = [UnsafePointer<Int8>?]()
    for dref in drefs {
        cDrefs.append(dref.cString(using: .utf8))
    }
    let result = getDREFs(&cDrefs, UInt8(drefs.count))
    return Int(result)
}

但是快速测试显示,如果调用则不起作用 多个字符串。原因是阵列 由dref.cString(using: .utf8)返回 已经可以解除分配(并且指针无效) 当调用C函数时。

这是一个工作版本,略有修改 Convert a Swift Array of String to a to a C string array pointer 这个特例:

public func get(drefs: [String]) -> Int {
    var cargs = drefs.map { UnsafePointer<Int8>(strdup($0)) }
    let result = getDREFs(&cargs, UInt8(drefs.count))
    for ptr in cargs { free(UnsafeMutablePointer(mutating: ptr)) }
    return Int(result)
}