[英]Convert an String to an array of int8
I have an C struct (old library, blah blah blah) which contains an C string, now I need to convert CFString and Swift strings into this c string. 我有一个C结构(旧库,blah blah blah),它包含一个C字符串,现在我需要将CFString和Swift字符串转换为这个c字符串。 Something like
就像是
struct Product{
char name[50];
char code[20];
}
So I'm trying to assign it as 所以我试着把它指定为
productName.getCString(&myVarOfStructProduct.name, maxLength: 50, encoding: NSUTF8StringEncoding)
but the compiler is giving me the following error: cannot convert type (int8, int8, int8....) to [CChar]. 但是编译器给出了以下错误:无法将类型(int8,int8,int8 ....)转换为[CChar]。
A possible solution: 可能的解决方案:
withUnsafeMutablePointer(&myVarOfStructProduct.name) {
strlcpy(UnsafeMutablePointer($0), productName, UInt(sizeofValue(myVarOfStructProduct.name)))
}
Inside the block, $0
is a (mutable) pointer to the tuple. 在块内,
$0
是指向元组的(可变)指针。 This pointer is converted to an UnsafeMutablePointer<Int8>
as expected by the BSD library function strlcpy()
. 正如BSD库函数
strlcpy()
所期望的那样,该指针被转换为UnsafeMutablePointer<Int8>
。
It also uses the fact that the Swift string productName
is automatically to UnsafePointer<UInt8>
as explained in String value to UnsafePointer<UInt8> function parameter behavior . 它还使用一个事实,即夫特串
productName
自动是UnsafePointer<UInt8>
如在解释字符串值到UnsafePointer <UINT8>功能参数行为 。 As mentioned in the comments in that thread, this is done by creating a temporary UInt8
array (or sequence?). 正如该线程中的注释所述,这是通过创建临时
UInt8
数组(或序列?)来完成的。 So alternatively you could enumerate the UTF-8 bytes explicitly and put them into the destination: 所以, 或者你可以明确地列举了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.
}
Yet another possible solution (with an intermediate NSData
object): 另一种可能的解决方案(使用中间
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))
}
Update for Swift 3: Swift 3更新:
withUnsafeMutablePointer(to: &myVarOfStructProduct.name) {
$0.withMemoryRebound(to: Int8.self, capacity: MemoryLayout.size(ofValue: myVarOfStructProduct.name)) {
_ = strlcpy($0, productName, MemoryLayout.size(ofValue: myVarOfStructProduct.name))
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.