Swift 中的新@convention(c) 2:如何使用它?

New @convention(c) in Swift 2: How can I use it?

迁移到 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 中创建一个 CFunctionPointer。相反,您可以通过调用约定来注释您的类型,在本例中 c,并直接使用它。

typealias CFunction = @convention(c) (UnsafeMutablePointer<Void>, Float) -> Int
let bar = unsafeBitCast(foo, CFunction.self)

The Swift Programming Language 的类型属性部分中 @convention 描述的相关位是:

The c argument is used to indicate a C function reference. The function value carries no context and uses the C calling convention.

将 Swift 闭包传递给采用函数指针的 C 函数 Swift 2 现在支持参数,而且,正如您所注意到的,函数 类型由 @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