我正在从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>?>!'
我错过了什么?
答案 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)
}