将字符串转换为 int8 数组 [英] Convert an String to an array of int8

查看:39
本文介绍了将字符串转换为 int8 数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含 C 字符串的 C 结构(旧库,等等),现在我需要将 CFString 和 Swift 字符串转换为这个 C 字符串.类似的东西

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. 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)

但是编译器给了我以下错误:cannot convert type (int8, int8, int8....) to [CChar].

but the compiler is giving me the following error: cannot convert type (int8, int8, int8....) to [CChar].

推荐答案

一个可能的解决方案:

withUnsafeMutablePointer(&myVarOfStructProduct.name) {
    strlcpy(UnsafeMutablePointer($0), productName, UInt(sizeofValue(myVarOfStructProduct.name)))
}

在块内部,$0 是指向元组的(可变)指针.这个指针是如预期的那样转换为 UnsafeMutablePointerBSD库函数strlcpy().

Inside the block, $0 is a (mutable) pointer to the tuple. This pointer is converted to an UnsafeMutablePointer<Int8> as expected by the BSD library function strlcpy().

它还使用了 Swift 字符串 productName 自动UnsafePointerString value to UnsafePointer 中所述.函数参数行为.正如评论中提到的那样线程,这是通过创建一个临时的 UInt8 数组(或序列?)来完成的.因此,或者您可以显式枚举 UTF-8 字节并将它们放入进入目的地:

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. As mentioned in the comments in that thread, this is done by creating a temporary UInt8 array (or sequence?). So alternatively you could enumerate the UTF-8 bytes explicitly and put them into the destination:

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 对象):

Yet another possible solution (with an intermediate NSData object):

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, productName, MemoryLayout.size(ofValue: myVarOfStructProduct.name))
    }
}

这篇关于将字符串转换为 int8 数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆