我正在使用Swift 3为C库构建一个包装器/接口。我需要调用的一个函数需要一个函数指针作为参数进行回调。
详细说明:在所述函数成功完成文件操作后,它会调用给定参数指针引用的函数 - 基本上让我用所述数据做其他操作
该功能如下所示:
HSYNC MXDEF (Syncer)(DWORD h, DWORD t, QWORD p, SYNCPROC *proc, void *user);
回调函数类型SYNCPROC
定义如下:
typedef void (CALLBACK SYNCPROC)(HSYNC h, DWORD c, DWORD d, void *user);
到目前为止,我只能使用Syncer
函数将回调参数设置为 nil 。
我尝试在Class之外创建一个函数:
func callbackCalled(handle: HSYNC, channel: DWORD, data: DWORD, user: UnsafeMutableRawPointer) -> Void {
print("callback called")
}
我甚至在课堂上尝试过这种方法:
var callbackTest : @convention(c) (_ handle: HSYNC, _ channel: DWORD, _ data: DWORD, _ user: UnsafeMutableRawPointer) -> Void = {
print("\($0) \($1) \($2) \($3)")
}
但是我尝试/阅读了这个主题,我总是得到这个错误信息:
Cannot convert value of type 'Void' (aka '()') to expected argument type '(@convention(c) (HSYNC, DWORD, DWORD, UnsafeMutableRawPointer?) -> Void)!'
我的问题是:我应该如何满足有关此类回调函数的标准?
我还没有找到关于这些类型的回调函数的任何信息,可能是由于我缺乏知识和对问题的透彻理解。提前谢谢!
答案 0 :(得分:4)
传递全局函数作为回调应该有效,但是最后一个参数
必须是可选的UnsafeMutableRawPointer?
:
func callbackCalled(handle: HSYNC, channel: DWORD, data: DWORD, user: UnsafeMutableRawPointer?) -> Void {
print("callback called")
}
Syncer(h, c, d, callbackCalled, u)
或者,传递一个闭包表达式(让编译器推断出来) 参数的类型):
Syncer(h, d, c, {
(handle, channel, data, user) in
// ...
}, u)
您可以不传递实例方法作为回调,比较 How to use instance method as callback for function which takes only func or literal closure
如果NULL
不是用户参数的有效值,那么您可以
加
{C}声明"Nullability annotations",例如
typedef void (CALLBACK SYNCPROC)(HSYNC h, DWORD c, DWORD d, void * _Nonnull user);
然后它将在Swift中表示为非可选的UnsafeMutableRawPointer
。