37

迁移到 Swift 2 后,我遇到了这个问题,错误提示我现在应该使用 @convention(c) (T) -> U。我已经尝试了排列,但到目前为止还没有运气。

func foo(context: AnyObject?, width: CGFloat) -> Int {

}

let bar = unsafeBitCast(foo, CFunctionPointer<(UnsafeMutablePointer<Void>, Float) -> Int>.self)
4

2 回答 2

32

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
于 2015-06-10T03:06:23.223 回答
22

您不再需要在 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 调用约定。

于 2015-06-09T19:07:27.030 回答