在 Swift 中初始化 C 结构体
Posted
技术标签:
【中文标题】在 Swift 中初始化 C 结构体【英文标题】:Initializing C structs in Swift 【发布时间】:2014-08-03 23:43:46 【问题描述】:我在从 Swift 调用 statfs() 时遇到问题。该调用使用一个也称为 statfs 的结构作为参数,而 swift 编译器似乎将两者混淆了。
这段代码告诉我该结构未初始化,因此无法编译:
var sb : statfs
if(statfs(fd, &sb) == 0)
//...
但是当我尝试初始化结构时(我尝试过 "var sb : statfs = statfs()" 和 "var sb : statfs = statfs(f_bsize: 0, f_iosize: 0, ...)" ,它告诉我参数不匹配,它似乎在寻找函数的参数而不是结构。
所以,我猜我必须缺少一些语法糖,才能让编译器意识到它应该查看结构而不是函数。
我有一个类似的命名问题,这更让人不便:我想有一个名为 open() 的类,它调用 posix 命令 open(),但我无法让编译器意识到我想要调用 posix 命令而不是我自己的方法。我通过简单地重命名我的方法来解决这个问题,但是当存在多个同名项目时,必须有一些语法让编译器知道你指的是哪个项目。
【问题讨论】:
【参考方案1】:问题在于 Swift 将函数名和结构名都导入为statfs
。您可以通过 typealias 消除它们的歧义。
/// universal initializer
func blankof<T>(type:T.Type) -> T
var ptr = UnsafeMutablePointer<T>.alloc(sizeof(T))
var val = ptr.memory
ptr.destroy()
return val
import Darwin
typealias StatFS = statfs // this does the trick
var fs = blankof(StatFS)
println(statfs("/", &fs))
println(fs.f_ffree)
【讨论】:
这很好用!但是,在查看文档后: UnsafeMutablePointer.alloc 的参数是 T 的多个值,而不是字节 - 所以这里应该是“1”。此外,ptr.move() 被记录为与 .memory 和 .destroy() 执行相同的操作,但速度更快,因此您可以将其减少到一行。【参考方案2】:关于你的第二个问题(你应该把它单独做一个吗?;-):
我希望有一个名为 open() 的类,它调用 posix 命令 open(),但我无法让编译器意识到我想调用 posix 命令而不是我自己的方法。
试试这个:
func open(x, y)
Darwin.open(x, y)
就像在这里: https://github.com/AlwaysRightInstitute/SwiftSockets/blob/master/ARISockets/Socket.swift#L99
【讨论】:
以上是关于在 Swift 中初始化 C 结构体的主要内容,如果未能解决你的问题,请参考以下文章