在Swift 3(libxml2)中将String转换为UnsafePointer <xmlChar>的更快捷的方法

vad*_*ian 6 unsafe-pointers libxml2 swift swift3

我正在为libxml2 C库开发一个Swift 3包装器.

转换String为两种便捷方法,UnsafePointer<xmlChar>反之亦然.在libxml2 xmlChar中声明为unsigned char.

  • UnsafePointer<xmlChar>String是简单

    func stringFrom(xmlchar: UnsafePointer<xmlChar>) -> String {
        let string = xmlchar.withMemoryRebound(to: CChar.self, capacity: 1) {
            return String(validatingUTF8: $0)
        }
        return string ?? ""
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 对于StringUnsafePointer<xmlChar>我试过,例如很多事情

    let bytes = string.utf8CString.map{ xmlChar($0) }
    return UnsafePointer<xmlChar>(bytes)
    
    Run Code Online (Sandbox Code Playgroud)

    但这不起作用,我发现的唯一可行解决方案是

    func xmlCharFrom(string: String) -> UnsafePointer<xmlChar> {
        let pointer = (string as NSString).utf8String
        return unsafeBitCast(pointer, to: UnsafePointer<xmlChar>.self)
    }
    
    Run Code Online (Sandbox Code Playgroud)

有没有更好的,swiftier没有桥投地的方式NSStringunsafeBitCast

Cha*_*tka 6

我能想到的最快的方法就是使用bitPattern:初始化程序:

let xmlstr = str.utf8CString.map { xmlChar(bitPattern: $0) }

这会给你一个ArrayxmlChar秒.坚持下去,当你需要传递给某个东西时使用Array's withUnsafeBufferPointer方法UnsafePointer:

xmlstr.withUnsafeBufferPointer { someAPIThatWantsAPointer($0.baseAddress!) }

不要让UnsafePointer关闭逃脱,因为它在外面是无效的.

编辑:如何妥协?不要让你的函数返回一个指针,而是让它关闭.

func withXmlString<T>(from string: String, handler: (UnsafePointer<xmlChar>) throws -> T) rethrows -> T {
    let xmlstr = string.utf8CString.map { xmlChar(bitPattern: $0) }

    return try xmlstr.withUnsafeBufferPointer { try handler($0.baseAddress!) }
}
Run Code Online (Sandbox Code Playgroud)

或者,作为扩展String:

extension String {
    func withXmlString<T>(handler: (UnsafePointer<xmlChar>) throws -> T) rethrows -> T {
        let xmlstr = self.utf8CString.map { xmlChar(bitPattern: $0) }

        return try xmlstr.withUnsafeBufferPointer { try handler($0.baseAddress!) }
    }
}
Run Code Online (Sandbox Code Playgroud)