在 Swift 2.0 中实现 c 函数回调?
Implementing a c function callback in Swift 2.0?
CFReadStreamSetClient
在其初始化程序中有一个 C 函数回调 (CFReadStreamClientCallBack
),
CFReadStreamClientCallback
看起来像这样:
typealias CFReadStreamClientCallBack = (CFReadStream!,
CFStreamEventType, UnsafeMutablePointer<Void>) -> Void
我有一个尝试处理 CFReadStreamClientCallBack
C 函数回调的方法:
func callback(stream: CFReadStreamRef,
eventType: CFStreamEventType,
inClientInfo: UnsafeMutablePointer<Void>) {
}
但是当我尝试按如下方式在 CFReadStreamCallback
中设置回调时,它无法编译。
CFReadStreamSetClient(stream, registeredEvents, callback, clientContextPtr)
我知道 Swift 2.0 有一种方法可以将 Swift 闭包与 C 函数回调一起使用,但我似乎无法让它工作。有谁知道在这种情况下该怎么做?
你可以创建一个闭包来完成你在函数中所做的事情:
CFReadStreamSetClient(stream, registeredEvents, { readStream, event, data -> Void in
// Do stuff here.
}, clientContextPtr)
另请注意,C 函数块不能有上下文,因此您无法访问自身或块外的任何其他变量。
如果这不起作用,您能否在您的问题中包含编译器错误?
Swift 2.0:
给定一个接受函数指针和上下文的函数:
void c_func_with_callback(void *context, void (*callback)(void *context))
很容易从 Swift 调用它,但无法访问封闭 class 的变量:
c_func_with_callback(nil) { context in
print("Callback in Swift!") // OK
self.xxx // error
}
如果您需要访问块外的变量,可以使用上下文来存储指向 class 的指针:
class MyClass {
func hello() {
print("MyClass.hello()")
}
func classMethodAsCallback() {
let context = unsafeBitCast(self, UnsafeMutablePointer<Void>.self)
c_func_with_callback(context) { context in
let caller = unsafeBitCast(context, MyClass.self)
caller.hello()
}
}
}
let myClass = MyClass()
myClass.classMethodAsCallback()
甚至可以使用任何闭包作为回调:
class MyClass {
typealias Closure = ()->()
func anySwiftClosureAsCallback(closure: Closure) {
var c = closure
// closure won't fit in a pointer, so take it's address first
let context = withUnsafePointer(&c) {
//(ptr: UnsafePointer<Closure>) -> UnsafeMutablePointer<Void> in
ptr in
return unsafeBitCast(ptr, UnsafeMutablePointer<Void>.self)
}
c_func_with_callback(context) { context in
let ptr = unsafeBitCast(context, UnsafePointer<Closure>.self)
let closure = ptr.memory // dereference the address
closure()
}
}
}
let myClass = MyClass()
myClass.anySwiftClosureAsCallback {
print("Swift closure called")
}
CFReadStreamSetClient
在其初始化程序中有一个 C 函数回调 (CFReadStreamClientCallBack
),
CFReadStreamClientCallback
看起来像这样:
typealias CFReadStreamClientCallBack = (CFReadStream!,
CFStreamEventType, UnsafeMutablePointer<Void>) -> Void
我有一个尝试处理 CFReadStreamClientCallBack
C 函数回调的方法:
func callback(stream: CFReadStreamRef,
eventType: CFStreamEventType,
inClientInfo: UnsafeMutablePointer<Void>) {
}
但是当我尝试按如下方式在 CFReadStreamCallback
中设置回调时,它无法编译。
CFReadStreamSetClient(stream, registeredEvents, callback, clientContextPtr)
我知道 Swift 2.0 有一种方法可以将 Swift 闭包与 C 函数回调一起使用,但我似乎无法让它工作。有谁知道在这种情况下该怎么做?
你可以创建一个闭包来完成你在函数中所做的事情:
CFReadStreamSetClient(stream, registeredEvents, { readStream, event, data -> Void in
// Do stuff here.
}, clientContextPtr)
另请注意,C 函数块不能有上下文,因此您无法访问自身或块外的任何其他变量。 如果这不起作用,您能否在您的问题中包含编译器错误?
Swift 2.0:
给定一个接受函数指针和上下文的函数:
void c_func_with_callback(void *context, void (*callback)(void *context))
很容易从 Swift 调用它,但无法访问封闭 class 的变量:
c_func_with_callback(nil) { context in
print("Callback in Swift!") // OK
self.xxx // error
}
如果您需要访问块外的变量,可以使用上下文来存储指向 class 的指针:
class MyClass {
func hello() {
print("MyClass.hello()")
}
func classMethodAsCallback() {
let context = unsafeBitCast(self, UnsafeMutablePointer<Void>.self)
c_func_with_callback(context) { context in
let caller = unsafeBitCast(context, MyClass.self)
caller.hello()
}
}
}
let myClass = MyClass()
myClass.classMethodAsCallback()
甚至可以使用任何闭包作为回调:
class MyClass {
typealias Closure = ()->()
func anySwiftClosureAsCallback(closure: Closure) {
var c = closure
// closure won't fit in a pointer, so take it's address first
let context = withUnsafePointer(&c) {
//(ptr: UnsafePointer<Closure>) -> UnsafeMutablePointer<Void> in
ptr in
return unsafeBitCast(ptr, UnsafeMutablePointer<Void>.self)
}
c_func_with_callback(context) { context in
let ptr = unsafeBitCast(context, UnsafePointer<Closure>.self)
let closure = ptr.memory // dereference the address
closure()
}
}
}
let myClass = MyClass()
myClass.anySwiftClosureAsCallback {
print("Swift closure called")
}