Using a C API function in Swift 3 that has a callback function pointer as an argument
c, callback, macos, swift
Solution
Passing a global function as callback should work, but the last parameter must be an optional `UnsafeMutableRawPointer?`:
func callbackCalled(handle: HSYNC, channel: DWORD, data: DWORD, user: UnsafeMutableRawPointer?) -> Void {
print("callback called")
}
Syncer(h, c, d, callbackCalled, u)
Alternatively, pass a closure expression (and let compiler infer the types of the parameters):
Syncer(h, d, c, {
(handle, channel, data, user) in
// ...
}, u)
You can not pass an instance method as a callback, compare How to use instance method as callback for function which takes only func or literal closure.
If `NULL` is not a valid value for the user parameter then you can add "Nullability annotations" to the C declaration, e.g.
typedef void (CALLBACK SYNCPROC)(HSYNC h, DWORD c, DWORD d, void * _Nonnull user);
and then it will be represented as a non-optional `UnsafeMutableRawPointer` in Swift.
Problem
I'm building a wrapper/interface for a C library with Swift 3. One of the functions that I need to call require a function pointer for callback as an argument. In detail: after said function has successfully done the file operation it has to, it then calls the function the given argument pointer refers to - essentially letting me do other operations with said data The function looks like this: `HSYNC MXDEF (Syncer)(DWORD h, DWORD t, QWORD p, SYNCPROC *proc, void *user);` The callback function type `SYNCPROC` is defined as follows: `typedef void (CALLBACK SYNCPROC)(HSYNC h, DWORD c, DWORD d, void *user);` I have only been able to use the `Syncer` function with setting the callback argument to nil so far. I tried creating a function outside the Class as someone suggested: `func callbackCalled(handle: HSYNC, channel: DWORD, data: DWORD, user: UnsafeMutableRawPointer) -> Void { print("callback called") }` And I even tried this method within the Class: `var callbackTest : @convention(c) (_ handle: HSYNC, _ channel: DWORD, _ data: DWORD, _ user: UnsafeMutableRawPointer) -> Void = { print("\($0) \($1) \($2) \($3)") }` But however I tried / read upon this topic I always end up with this error message: `Cannot convert value of type 'Void' (aka '()') to expected argument type '(@convention(c) (HSYNC, DWORD, DWORD, UnsafeMutableRawPointer?) -> Void)!'` My question is: How am I supposed to satisfy the criteria regarding this type of a callback function? I haven't been able to find any info regarding these types of callback functions, presumably due to my lack of knowledge and thorough understanding of the problem. Thank you in advance!