我有一个C结构(旧库,blah blah blah),它包含一个C字符串,现在我需要将CFString和
Swift字符串转换为这个c字符串.就像是
struct Product{ char name[50]; char code[20]; }
所以我试着把它指定为
productName.getCString(&myVarOfStructProduct.name,maxLength: 50,encoding: NSUTF8StringEncoding)
但是编译器给出了以下错误:无法将类型(int8,int8,int8 ….)转换为[CChar].
解决方法
可能的解决方案:
withUnsafeMutablePointer(&myVarOfStructProduct.name) { strlcpy(UnsafeMutablePointer($0),productName,UInt(sizeofValue(myVarOfStructProduct.name))) }
在块内,$0是指向元组的(可变)指针.这个指针是
转换为UnsafeMutablePointer< Int8>正如预期的那样
BSD library function strlcpy()
.
它还使用了Swift字符串productName自动生成的事实
到UnsafePointer< UInt8>
正如在String value to UnsafePointer<UInt8> function parameter behavior中所解释的那样.正如在评论中所提到的那样
线程,这是通过创建一个临时的UInt8数组(或序列?)来完成的.
因此,您可以显式枚举UTF-8字节并放置它们
进入目的地:
withUnsafeMutablePointer(&myVarOfStructProduct.name) { tuplePtr -> Void in var uint8Ptr = UnsafeMutablePointer<UInt8>(tuplePtr) let size = sizeofValue(myVarOfStructProduct.name) var idx = 0 if size == 0 { return } // C array has zero length. for u in productName.utf8 { if idx == size - 1 { break } uint8Ptr[idx++] = u } uint8Ptr[idx] = 0 // NUL-terminate the C string in the array. }
另一种可能的解决方案(使用中间NSData对象):
withUnsafeMutablePointer(&myVarOfStructProduct.name) { tuplePtr -> Void in let tmp = productName + String(UnicodeScalar(0)) // Add NUL-termination let data = tmp.dataUsingEncoding(NSUTF8StringEncoding,allowLossyConversion: true)! data.getBytes(tuplePtr,length: sizeofValue(myVarOfStructProduct.name)) }
Swift 3更新:
withUnsafeMutablePointer(to: &myVarOfStructProduct.name) { $0.withMemoryRebound(to: Int8.self,capacity: MemoryLayout.size(ofValue: myVarOfStructProduct.name)) { _ = strlcpy($0,MemoryLayout.size(ofValue: myVarOfStructProduct.name)) } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。