在Swift 3中使用C API函数,它具有回调函数指针作为参数

时间:2016-10-30 18:48:36

标签: c swift macos callback

我正在使用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)!'

我的问题是:我应该如何满足有关此类回调函数的标准?

我还没有找到关于这些类型的回调函数的任何信息,可能是由于我缺乏知识和对问题的透彻理解。提前谢谢!

1 个答案:

答案 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