我正在为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 ?? ""
    }
    
  • 对于StringUnsafePointer<xmlChar>,我尝试了很多事情,例如
    let bytes = string.utf8CString.map{ xmlChar($0) }
    return UnsafePointer<xmlChar>(bytes)
    

    但这是行不通的,我发现的唯一可行的解​​决方案是
    func xmlCharFrom(string: String) -> UnsafePointer<xmlChar> {
        let pointer = (string as NSString).utf8String
        return unsafeBitCast(pointer, to: UnsafePointer<xmlChar>.self)
    }
    

  • 如果没有将桥梁转换为NSStringunsafeBitCast的方法,是否有更好,更快捷的方法?

    最佳答案

    我能想到的最快方法是只使用bitPattern:初始化程序:
    let xmlstr = str.utf8CString.map { xmlChar(bitPattern: $0) }
    这将为您提供ArrayxmlChar。卡在上面,当您需要将Array传递给某些东西时,请使用withUnsafeBufferPointerUnsafePointer方法:
    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!) }
    }
    

    或者,作为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!) }
        }
    }
    

    关于swift - 在Swift 3(libxml2)中将字符串转换为UnsafePointer <xmlChar>的快捷方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45965523/

    10-10 20:01