'UnsafePointer <Int8>'不能转换为'UnsafePointer <_>

时间:2019-11-26 20:50:09

标签: swift libssh2 unsafe-pointers

我正在尝试使用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。关于如何正确转换指针的任何想法?

1 个答案:

答案 0 :(得分:3)

data.withUnsafeBytesUnsafeRawBufferPointer调用闭包,必须将其“绑定”到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,所以无效。)