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

Lau*_*ent 31 swift swift2

迁移到Swift 2之后,我遇到了一个错误,说明我现在应该使用@convention(c)(T) - > U.我尝试了排列,但到目前为止还没有运气.

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

}

let bar = unsafeBitCast(foo, CFunctionPointer<(UnsafeMutablePointer<Void>, Float) -> Int>.self)
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 25

Swift 2现在支持将Swift闭包传递给带有函数指针参数的C函数,正如您所注意到的,函数类型是使用该@convention(c)属性指定的.

如果直接将闭包作为参数传递给C函数,则会自动推断此属性.

举个简单的例子,如果你有这个C函数

CGFloat myCFunction(CGFloat (callback)(CGFloat x, CGFloat y)) {
    return callback(1.1, 2.2);
}
Run Code Online (Sandbox Code Playgroud)

然后你可以从Swift中调用它

let result = myCFunction( {
    (x, y) -> CGFloat in
    return x + y
} )
print(result) // 3.3
Run Code Online (Sandbox Code Playgroud)

这与更详细的完全相同

let swiftCallback : @convention(c) (CGFloat, CGFloat) -> CGFloat = {
    (x, y) -> CGFloat in
    return x + y
} 

let result = myCFunction( swiftCallback )
print(result) // 3.3
Run Code Online (Sandbox Code Playgroud)


Mic*_*lum 19

您不再需要在Swift 2中创建CFunctionPointer.相反,您可以通过调用约定来注释您的类型,在这种情况下c,直接使用它.

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

Swift编程语言@convention的Type Attributes部分中描述的相关位是:

c参数用于表示C函数引用.函数值不携带上下文并使用C调用约定.

  • 谢谢.同时,我让它与let bar = foo一起工作@convention(c)(AnyObject?,CGFloat) - > Int (3认同)
  • 呃,@ convention(c)(UnsafeMutablePointer <Void>?,CGFloat) - > Int因为AnyObject?显然不可转换.我也不得不在我的被叫方法签名中使用unsafebitcast. (2认同)