I have a very simple function in C and its pointer gets passed into Swift.
void callback() {
NSLog(@"such pointer…");
}
How can it be invoke in Swift using ONLY the pointer? This is NOT about simply invoking it – it works fine when invoked directly. Tried the following and different variations with signature casting, but it always crashes:
let pointer: UnsafePointer<@convention(c)() -> ()> = UnsafePointer(bitPattern: …)
let callback: @convention(c)() -> () = pointer.memory
Swift.print(callback) // (Function)
callback() // Handling crash with signal 11...
Tried defining Callback
type with typedef void(*Callback)();
– same thing:
let pointer: UnsafePointer<Callback> = UnsafePointer(bitPattern: …)
let callback: Callback = pointer.memory
Swift.print(callback) // (Function)
callback() // Handling crash with signal 11...
To check that it actually works and points to the right address I have another Objective-C function, which works as expected when invoked from Swift with the callback pointer.
void invokeCallback(uintptr_t callback) {
((void (*)()) callback)(); // such pointer…
}
The same approach as in Swift: How to call a C function loaded from a dylib should work here.
Example for Swift 3 (assuming that funcPtr
is a
UnsafeRawPointer
containing the function's address):
// Define function type:
typealias callbackFunc = @convention(c) () -> Void
// Convert pointer to function type:
let callback = unsafeBitCast(funcPtr, to: callbackFunc.self)
// Call function:
callback()
Of course the type alias must match the actual function signature, and the function needs to be a "pure" C function (not an Objective-C method).