我正在为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 ?? ""
}
String
到UnsafePointer<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)
}
如果没有将桥梁转换为
NSString
和unsafeBitCast
的方法,是否有更好,更快捷的方法? 最佳答案
我能想到的最快方法是只使用bitPattern:
初始化程序:let xmlstr = str.utf8CString.map { xmlChar(bitPattern: $0) }
这将为您提供Array
的xmlChar
。卡在上面,当您需要将Array
传递给某些东西时,请使用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!) }
}
或者,作为
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/