【问题标题】:New @convention(c) in Swift 2: How can I use it?Swift 2 中的新 @convention(c):我该如何使用它?
【发布时间】:2015-06-09 18:58:25
【问题描述】:

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

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

}

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

【问题讨论】:

  • 我认为应该可以完全避免 unsafeBitCast。你能提供更多信息吗? C 函数是如何声明的,作为上下文对象传递的是什么,...?
  • 这也可能有助于通过 C 回调传递对象指针:stackoverflow.com/questions/30786883/…
  • CGFloatFloat 不同。在 64 位平台上(即过去几年的所有 Apple 设备)它是 Double,而在 32 位平台上它是 Float。然而,在 Objective-C 中 CGFloat 只是一个普通的 C typedef,所以你应该在这里使用 CGFloat

标签: swift swift2


【解决方案1】:

将 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

【讨论】:

  • char数组怎么做?
【解决方案2】:

您不再需要在 Swift 2 中创建 CFunctionPointer。相反,您可以通过调用约定来注释您的类型,在本例中为 c,并直接使用它。

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

The Swift Programming Language 的 Type Attributes 部分中 @convention 描述的相关位是:

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

【讨论】:

  • 谢谢。同时,我让它与 let bar = foo as @convention(c) (AnyObject?, CGFloat) -> Int 一起工作
  • 呃,@convention(c) (UnsafeMutablePointer?, CGFloat) -> Int 因为 AnyObject?显然不能兑换。我也不得不在我调用的方法签名中进行 unsafebitcast。
  • 当直接从像 CFunction.self 这样的类型调用时,.self 是什么意思?
  • 当心,不要在函数类型之间进行不安全的位转换。 @convention(c) 的意义在于它改变了应用它的函数的调用约定。通过位转换,您可以防止类型系统诊断问题,但您实际上并没有改变函数处理其参数的方式——因此您将得到一个与其说不同语言的损坏函数来电者。 (对于带有 AnyObject 参数的函数尤其如此。)
猜你喜欢
  • 2017-03-01
  • 1970-01-01
  • 2014-10-15
  • 1970-01-01
  • 1970-01-01
  • 2011-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多