我有一个Swift程序,可以与C库互操作。这个C库返回一个内部带有char[]数组的结构,如下所示:
char[]
struct record { char name[8]; };
该定义已正确导入到Swift中。但是,该字段被解释为8个元素(类型为)的 元组 ,我不知道如何使用Swift 将其转换为a 。Int8``(Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8)``String
Int8``(Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8)``String
没有String可以接受Int8元组的初始化程序,并且似乎不可能获得指向元组的第一个元素的指针(因为类型可以是异构的,这并不奇怪)。
String
Int8
现在,我最好的主意是创建一个微型C函数,该函数接受指向结构本身name的char*指针,并以指针(而不是数组)的形式返回,然后继续。
name
char*
但是,那里有纯粹的Swift方法吗?
C数组char name[8]作为元组导入到Swift:
char name[8]
(Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8)
如Apple工程师Joe Groff所确认,name的地址与的地址相同name[0],并且Swift 保留 了从C导入的结构的内存布局。
name[0]
…您可以保留在C中定义的结构,并将其导入Swift。Swift将尊重C的布局。
结果,我们可以将的地址(record.name转换为UInt8指针)传递给String初始化程序:
record.name
UInt8
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) } }
注意: 假定其中的字节name[]是有效的NUL终止的UTF-8序列。
name[]