在Swift中使用termios [英] Using termios in Swift

查看:113
本文介绍了在Swift中使用termios的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Now that we've reached Swift 2.0, I've decided to convert my, as yet unfinished, OS X app to Swift. Making progress but I've run into some issues with using termios and could use some clarification and advice.

termios结构在Swift中被视为结构,这并不奇怪,但是令人惊讶的是,该结构中的控制字符数组现在是一个元组.我期望它只是一个数组.就像您可能想像的那样,我花了一些时间才弄清楚这一点.如果可以,请在操场上工作:

The termios struct is treated as a struct in Swift, no surprise there, but what is surprising is that the array of control characters in the struct is now a tuple. I was expecting it to just be an array. As you might imagine it took me a while to figure this out. Working in a Playground if I do:

var settings:termios = termios()
print(settings)

然后我得到了为该结构打印的正确详细信息.

then I get the correct details printed for the struct.

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

In Obj-C to set the control characters you would use, say,

cfmakeraw(&settings);
settings.c_cc[VMIN] = 1;

其中VMIN是termios.h中等于16的#define.在Swift中,我必须做

where VMIN is a #define equal to 16 in termios.h. In Swift I have to do

cfmakeraw(&settings)
settings.c_cc.16 = 1

可以,但是有点不透明.我宁愿使用类似

which works, but is a bit more opaque. I would prefer to use something along the lines of

settings.c_cc.vim = 1

而是,但是似乎找不到任何描述termios的Swift版本"的文档.没有人知道元组是否为其元素预先分配了名称,是否有办法在事实之后分配名称?我是否应该只使用命名元素创建自己的元组,然后将其分配给settings.c_cc?

instead, but can't seem to find any documentation describing the Swift "version" of termios. Does anyone know if the tuple has pre-assigned names for it's elements, or if not, is there a way to assign names after the fact? Should I just create my own tuple with named elements and then assign it to settings.c_cc?

有趣的是,即使我愿意,预处理器指令也不应该在Swift中运行

Interestingly, despite the fact that pre-processor directives are not supposed to work in Swift, if I do

print(VMIN)
print(VTIME)

然后将打印正确的值,并且不会产生编译器错误.我对此有任何澄清或评论感兴趣.是虫子吗?

then the correct values are printed and no compiler errors are produced. I'd be interested in any clarification or comments on that. Is it a bug?

其余问题与Termios的进一步配置有关.

The remaining issues have to do with further configuration of the termios.

cfsetspeed的定义为

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

speed_t被定义为无符号长型.在Obj-C中,我们要做

and speed_t is typedef'ed as an unsigned long. In Obj-C we'd do

cfsetspeed(&settings, B38400);

,但是由于B38400是termios.h中的#define,因此我们不能再这样做了.苹果公司是否已在Swift中为此类设置了替换全局常量,如果可以的话,谁能告诉我它们的记录位置.替代方法似乎是仅插入原始值并失去可读性,或创建我自己的termios.h中定义的常量版本.如果没有更好的选择,我很乐意走这条路.

but since B38400 is a #define in termios.h we can no longer do that. Has Apple set up replacement global constants for things like this in Swift, and if so, can anyone tell me where they are documented. The alternative seems to be to just plug in the raw values and lose readability, or to create my own versions of the constants previously defined in termios.h. I'm happy to go that route if there isn't a better choice.

推荐答案

让我们从第二个问题开始,这很容易解决. B38400 在Swift中可用,只是类型错误. 因此,您必须对其进行显式转换:

Let's start with your second problem, which is easier to solve. B38400 is available in Swift, it just has the wrong type. So you have to convert it explicitly:

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


您的第一个问题没有好"的答案.我所知道的解决方案. 固定大小的数组作为元组导入到Swift中,据我所知,您不能使用变量来处理元组元素.


Your first problem has no "nice" solution that I know of. Fixed sized arrays are imported to Swift as tuples, and – as far as I know – you cannot address a tuple element with a variable.

但是,Swift 保留从C导入的结构的内存布局,如下 由苹果工程师Joe Groff确认:.因此,您可以获取元组的地址,并将其重新绑定"到指向元素类型的指针:

However,Swift preserves the memory layout of structures imported from C, as confirmed by Apple engineer Joe Groff:. Therefore you can take the address of the tuple and "rebind" it to a pointer to the element type:

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+更新.)

(Code updated for Swift 4+.)

这篇关于在Swift中使用termios的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆