zne*_*eak 22 arrays interop tuples swift
我有一个与C库互操作的Swift程序.这个C库返回一个char[]
内部有数组的结构,如下所示:
struct record
{
char name[8];
};
Run Code Online (Sandbox Code Playgroud)
该定义被正确导入Swift.但是,该字段被解释为8个元素(类型)的元组,我不知道如何使用Swift 转换为a .Int8
(Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8)
String
没有String
接受Int8
元组的初始化器,并且似乎不可能获得指向元组的第一个元素的指针(因为类型可以是异构的,这并不奇怪).
现在,我最好的想法是创建一个微小的C函数,它接受一个指向结构本身的指针,并name
作为char*
指针而不是数组返回,并继续使用它.
然而,是否有纯粹的Swift方式呢?
Mar*_*n R 26
C数组char name[8]
作为元组导入Swift:
(Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8)
Run Code Online (Sandbox Code Playgroud)
地址与地址name
相同name[0]
,Swift 保留从C导入的结构的内存布局,
Apple工程师Joe Groff证实:
...您可以保留在C中定义的结构并将其导入Swift.斯威夫特将尊重C的布局.
因此,我们可以将record.name
转换为UInt8
指针的地址传递给String初始值设定项:
var record = someFunctionReturningAStructRecord()
// Swift 2:
let name = withUnsafePointer(&record.name) {
String.fromCString(UnsafePointer($0))!
}
// Swift 3:
let name = withUnsafePointer(to: &record.name) {
$0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: record.name)) {
String(cString: $0)
}
}
Run Code Online (Sandbox Code Playgroud)
注意:假设字节name[]
是有效的NUL终止的UTF-8序列.