我正在尝试使用Swift来实现围绕libssh2编写包装器。以下代码用于通过SFTP删除文件。
func removeFile(_ path: String) {
let data = path.data(using: String.Encoding.utf8)!
let result = data.withUnsafeBytes { (pointer: UnsafePointer<Int8>) -> Int in
return libssh2_sftp_unlink_ex(sftpHandle, pointer, data.count)
}
}
对于pointer: UnsafePointer<Int8>
,我收到以下错误消息:
'UnsafePointer<Int8>' is not convertible to 'UnsafePointer<_>
我发现this个主题与UInt8
类似的问题有关。我尝试删除演员表,但遇到下一个错误:
'Swift.UnsafePointer<_>' is not convertible to 'Swift.UnsafePointer<_>'
使用伪指针在闭包外部运行libssh2_sftp_unlink_ex(sftpHandle, pointer, data.count)
。
我还找到了将字符串转换为UInt8
的{{3}}答案,问题是我无法将其移植到Int8
。关于如何正确转换指针的任何想法?
答案 0 :(得分:3)
data.withUnsafeBytes
用UnsafeRawBufferPointer
调用闭包,必须将其“绑定”到UnsafePointer<Int8>
。还必须将data.count
转换为UInt32
(又名CUnsignedInt
),因为这是将C类型unsigned integer
导入到Swift的方式:
func removeFile(_ path: String) {
let data = path.data(using: String.Encoding.utf8)!
let result = data.withUnsafeBytes {
libssh2_sftp_unlink_ex(sftpHandle,
$0.bindMemory(to: Int8.self).baseAddress,
UInt32(data.count))
}
}
或者,使用withCString()
的{{1}}方法:
String
更简单:使用仅需要C字符串而不需要显式字符串长度的变体。在这里,编译器自动创建将Swift字符串转换为临时C字符串的代码:
func removeFile(_ path: String) {
let result = path.withCString {
libssh2_sftp_unlink_ex(sftpHandle, $0, UInt32(strlen($0)))
}
}
(因为func removeFile(_ path: String) {
let result = libssh2_sftp_unlink(sftpHandle, path)
}
是宏且未导入到Swift,所以无效。)