Macos 在Swift中使用termios

Macos 在Swift中使用termios,macos,swift,swift2,termios,Macos,Swift,Swift2,Termios,现在我们已经达到Swift 2.0,我决定将我尚未完成的OSX应用程序转换为Swift。正在取得进展,但我在使用termios时遇到了一些问题,需要一些澄清和建议 termios结构在Swift中被视为一个结构,这并不奇怪,但令人惊讶的是,结构中的控制字符数组现在是一个元组。我希望它只是一个数组。你可以想象,我花了一段时间才弄明白。在操场上工作,如果我这样做: var settings:termios = termios() print(settings) 然后,我将为结构打印正确的详细信息

现在我们已经达到Swift 2.0,我决定将我尚未完成的OSX应用程序转换为Swift。正在取得进展,但我在使用termios时遇到了一些问题,需要一些澄清和建议

termios结构在Swift中被视为一个结构,这并不奇怪,但令人惊讶的是,结构中的控制字符数组现在是一个元组。我希望它只是一个数组。你可以想象,我花了一段时间才弄明白。在操场上工作,如果我这样做:

var settings:termios = termios()
print(settings)
然后,我将为结构打印正确的详细信息

在Obj-C中设置要使用的控制字符,例如

cfmakeraw(&settings);
settings.c_cc[VMIN] = 1;
其中,
VMIN
是一个#定义,等于16 in termios.h。在斯威夫特,我必须这样做

cfmakeraw(&settings)
settings.c_cc.16 = 1
这是可行的,但有点不透明。我更喜欢使用类似于

settings.c_cc.vim = 1
相反,但似乎找不到任何描述termios Swift“版本”的文档。有人知道元组是否为其元素预先指定了名称,或者如果没有,是否有一种方法可以在事件发生后指定名称?我是否应该用命名元素创建自己的元组,然后将其分配给
settings.c_cc

有趣的是,尽管事实上预处理器指令不应该在Swift中工作,如果我这样做的话

print(VMIN)
print(VTIME)
然后打印正确的值,不会产生编译器错误。我想了解关于这方面的任何澄清或评论。是虫子吗

剩下的问题与termios的进一步配置有关

cfsetspeed
的定义如下

func cfsetspeed(_: UnsafeMutablePointer<termios>, _: speed_t) -> Int32

但是由于B38400是termios.h中的一个定义,我们不能再这样做了。苹果公司是否在Swift中为类似的东西设置了替换全局常量,如果是这样,有谁能告诉我它们在哪里被记录。另一种选择似乎是只插入原始值而失去可读性,或者创建我自己的版本的先前在termios.h中定义的常量。如果没有更好的选择,我很乐意走这条路。

让我们从第二个问题开始,它更容易解决。
B38400
在Swift中可用,只是类型错误。 因此,您必须显式地转换它:

var settings = termios()
cfsetspeed(&settings, speed_t(B38400))

据我所知,你的第一个问题没有“好”的解决方案。 固定大小的数组作为元组导入到Swift中,而且——据我所知——您不能用变量寻址元组元素

但是,Swift保留了从C导入的结构的内存布局,如下所示 . 因此,您可以获取元组的地址并将其“重新绑定”到指向元素类型的指针:

var settings = termios()
withUnsafeMutablePointer(to: &settings.c_cc) { (tuplePtr) -> Void in
    tuplePtr.withMemoryRebound(to: cc_t.self, capacity: MemoryLayout.size(ofValue: settings.c_cc)) {
        $0[Int(VMIN)] = 1
    }
}
(针对Swift 4+更新的代码)

var settings = termios()
withUnsafeMutablePointer(to: &settings.c_cc) { (tuplePtr) -> Void in
    tuplePtr.withMemoryRebound(to: cc_t.self, capacity: MemoryLayout.size(ofValue: settings.c_cc)) {
        $0[Int(VMIN)] = 1
    }
}