Ответ 1
sys/utsname.h
импортируется в Swift по умолчанию, поэтому вам действительно не нужно импортировать его из заголовка моста. Но использование utsname
из Swift действительно болезненно, хотя Swift импортирует фиксированную длину массива C как кортежи. Если вы посмотрите на utsname.h
, вы увидите, что члены utsname
из C struct
- это все char
массив из 256 length:
#define _SYS_NAMELEN 256
struct utsname {
char sysname[_SYS_NAMELEN]; /* [XSI] Name of OS */
char nodename[_SYS_NAMELEN]; /* [XSI] Name of this network node */
char release[_SYS_NAMELEN]; /* [XSI] Release level */
char version[_SYS_NAMELEN]; /* [XSI] Version level */
char machine[_SYS_NAMELEN]; /* [XSI] Hardware type */
};
который импортируется в Swift следующим образом:
var _SYS_NAMELEN: Int32 { get }
struct utsname {
var sysname: (Int8, Int8, /* ... 254 more times "Int8, " here ... */) /* [XSI] Name of OS */
var nodename: (Int8, Int8, /* ... snip ... */ ) /* [XSI] Name of this network node */
var release: (Int8, Int8, /* ... snip ... */ ) /* [XSI] Release level */
var version: (Int8, Int8, /* ... snip ... */ ) /* [XSI] Version level */
var machine: (Int8, Int8, /* ... snip ... */ ) /* [XSI] Hardware type */
}
Да, это кортежи с 256 Int8
s. В каких случаях эта веселая автозаполнение в Xcode:
В настоящее время нет способа инициализировать кортеж в Swift без выписывания всего значения, поэтому инициализация его как локальной переменной будет довольно многословной, как вы видите выше. Также нет способа преобразовать кортеж в массив, так что огромный кортеж также не очень полезен.
Самое простое решение - реализовать его в Objective-C.
Если вы настроены на использование Swift, вы можете сделать это, но это не очень хорошо:
// Declare an array that can hold the bytes required to store `utsname`, initilized
// with zeros. We do this to get a chunk of memory that is freed upon return of
// the method
var sysInfo: [CChar] = Array(count: sizeof(utsname), repeatedValue: 0)
// We need to get to the underlying memory of the array:
let machine = sysInfo.withUnsafeMutableBufferPointer { (inout ptr: UnsafeMutableBufferPointer<CChar>) -> String in
// Call uname and let it write into the memory Swift allocated for the array
uname(UnsafeMutablePointer<utsname>(ptr.baseAddress))
// Now here is the ugly part: `machine` is the 5th member of `utsname` and
// each member member is `_SYS_NAMELEN` sized. We skip the the first 4 members
// of the struct which will land us at the memory address of the `machine`
// member
let machinePtr = advance(ptr.baseAddress, Int(_SYS_NAMELEN * 4))
// Create a Swift string from the C string
return String.fromCString(machinePtr)!
}