迁移到 Swift 2 后,我遇到了这个问题,错误提示我现在应该使用 @convention(c) (T) -> U。我已经尝试了排列,但到目前为止还没有运气。
func foo(context: AnyObject?, width: CGFloat) -> Int {
}
let bar = unsafeBitCast(foo, CFunctionPointer<(UnsafeMutablePointer<Void>, Float) -> Int>.self)
Swift 2 现在支持将 Swift 闭包传递给带有函数指针参数的 C 函数,并且,正如您所注意到的,函数类型是使用@convention(c)
属性指定的。
如果您将闭包直接作为参数传递给 C 函数,则自动推断此属性。
举个简单的例子,如果你有这个 C 函数
CGFloat myCFunction(CGFloat (callback)(CGFloat x, CGFloat y)) {
return callback(1.1, 2.2);
}
然后你可以从 Swift 调用它
let result = myCFunction( {
(x, y) -> CGFloat in
return x + y
} )
print(result) // 3.3
这与更详细的完全相同
let swiftCallback : @convention(c) (CGFloat, CGFloat) -> CGFloat = {
(x, y) -> CGFloat in
return x + y
}
let result = myCFunction( swiftCallback )
print(result) // 3.3
您不再需要在 Swift 2 中创建 CFunctionPointer。相反,您可以通过调用约定来注释您的类型,在这种情况下c
,并直接使用它。
typealias CFunction = @convention(c) (UnsafeMutablePointer<Void>, Float) -> Int
let bar = unsafeBitCast(foo, CFunction.self)
The Swift Programming Language@convention
的 Type Attributes 部分的描述的相关位是:
c 参数用于指示 C 函数引用。函数值不带上下文并使用 C 调用约定。