[英]A function to convert a C char array to a String
The statfs
struct in C has these char
array members: C语言中的
statfs
结构具有以下char
数组成员:
char f_mntonname[MNAMELEN]; /* directory on which mounted */
char f_mntfromname[MNAMELEN]; /* mounted file system */
The Swift type for these arrays in the Darwin.sys.mount
module is a tuple with 90 elements: Darwin.sys.mount
模块中这些数组的Swift类型是具有90个元素的元组:
public var f_mntonname: (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8,
...
Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8)
Another question about Converting a C char array to a String has an answer with code that I use twice in this example: 关于将C char数组转换为String的另一个问题是我在此示例中两次使用的代码的答案:
import Darwin.sys.mount
var vols: UnsafeMutablePointer<statfs>?
let count = getmntinfo(&vols, 0)
if let volsarray = vols, count > 0 {
for i in 0 ..< count {
var vol = volsarray[Int(i)]
let mntOnName = withUnsafePointer(to: &vol.f_mntonname) {
$0.withMemoryRebound(to: UInt8.self,
capacity: MemoryLayout.size(ofValue: vol.f_mntonname)) {
String(cString: $0)
}
}
let mntFromName = withUnsafePointer(to: &vol.f_mntfromname) {
$0.withMemoryRebound(to: UInt8.self,
capacity: MemoryLayout.size(ofValue: vol.f_mntfromname)) {
String(cString: $0)
}
}
print("on \(mntOnName) from \(mntFromName)")
}
}
To avoid repeating the code twice, I refactored the conversion code into the function below, but passing &vol.f_mntonname
to it won't compile, and I can't see a way to fix the problem by using a different type for the first argument. 为了避免重复两次代码,我将转换代码重构到下面的函数中,但是将
&vol.f_mntonname
传递给它不会编译,并且我看不到通过对第一个参数使用其他类型来解决问题的方法。
func charArrayToString(_ array: UnsafePointer<Int8>, capacity: Int) -> String {
return array.withMemoryRebound(to: UInt8.self, capacity: capacity) {
String(cString: $0)
}
}
var a = (Int8(65), Int8(66), Int8(67))
print(charArrayToString(&a, capacity: 3)) // doesn't compile
The compiler complains about call to charArrayToString
: 编译器抱怨调用
charArrayToString
:
Cannot convert value of type ' (Int8, Int8, Int8)
' to expected argument type ' Int8
' 无法将类型
(Int8, Int8, Int8)
'的值转换为预期的参数类型' Int8
'
It also complains when I pass a
instead of &a
: 当我通过
a
而不是&a
时,它也会抱怨:
Cannot convert value of type ' (Int8, Int8, Int8)
' to expected argument type ' UnsafePointer<Int8>
' 无法将类型
(Int8, Int8, Int8)
'的值转换为预期的参数类型' UnsafePointer<Int8>
'
You are trying to pass a pointer to a tuple as a point to a Int8
. 您正在尝试将指向元组的指针传递给
Int8
。 Instead you need to pass a pointer to the first element of the tuple. 相反,您需要将指针传递给元组的第一个元素。 For example define the function:
例如定义函数:
func charPointerToString(_ pointer: UnsafePointer<Int8>) -> String
{
return String(cString: UnsafeRawPointer(pointer).assumingMemoryBound(to: CChar.self))
}
(This function is adapted from and example in Apple's UnsafeRawPointer Migration ). (此功能改编自Apple的UnsafeRawPointer Migration中的示例 )。 Use this in your code to shorten your two
let
's passing a pointer to the first tuple element: 使用这个在你的代码,以缩短你的两个
let
的一个指针传递给第一个元组元素:
let mntOnName = charPointerToString(&vol.f_mntonname.0)
let mntFromName = charPointerToString(&vol.f_mntfromname.0)
However, despite that following the code in Apple's document it seems a bit overkill, you can also just: 但是,尽管遵循Apple文档中的代码似乎有点过大,但您也可以:
let mntOnName = String(cString: &vol.f_mntonname.0)
let mntFromName = String(cString: &vol.f_mntfromname.0)
(All code tested using Xcode 8.2.1.) (所有代码均使用Xcode 8.2.1进行了测试。)
HTH 高温超导
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.