17. Tips
⬛︎関数ポインタを渡す場合はいろいろと制約がある
・クロージャをC関数に渡そうとするとき、変数のキャプチャはできません。
<エラーの内容>
error: a C function pointer cannot be formed from a closure that captures context
・関数ポインタにはリテラククロジャーかトップレベルファンクションしか呼べません。
When calling a function that takes a function pointer
argument, you can pass a top-level Swift function, a
closure literal, or nil.
(Apple The Swift Programming Languageより)
・他にもErrorをthrowするクロージャを渡せないという制約がありますが、このTips
では扱いません。
18. Tips⬛︎対策
・呼び出せるタイプのクロージャから、本来呼び出したいクロージャを呼び出してあげる。
let calBackBag = unsafeBitCast(handle_addr, to: UnsafeMutablePointer<uv_stream_t>.self)
calBackBag.pointee.data = retainedVoidPointer { [unowned self]
(bytesRead:Int ,buffer:UVBuffer)->Void in
let uvData = UVData(lenBytes:bytesRead ,buffer: buffer)
callBack(self ,data: uvData)
}
uv_read_start(calBackBag, _alloc_buffer){ stream, bytesRead, buffer in
if let callback = unsafeFromVoidPointer(x: stream.pointee.data) as
((Int,UVBuffer) -> Void)? {
defer {
releaseRetainedPointer(x: callback)
buffer.pointee.base.deallocateCapacity(bytesRead)
}
呼び出せるタイプのクロージャ
呼び出せないタイプのクロージャ
(Selfをキャプチャしているため)
ここで本来呼び出したいクロージャを呼び出してい
る
Cから呼べないクロージャ
Cから呼べるクロージャ C関数
CallBack登録
呼び出し