Does Swift Not Work with Function Pointers

Does Swift not work with function pointers?

Apple has made function pointers available as of beta 3, however they can only be referenced not called.

Using Swift with Cocoa and Objective-C

Function Pointers


C function pointers are imported into Swift as CFunctionPointer<Type>, where Type is a
Swift function type. For example, a function pointer that has the type int (*)(void) in C
is imported into Swift as CFunctionPointer<() -> Int32>

Beta 3 Release Notes (PDF)

Function pointers are also imported now, and can be referenced and passed around. However,
you cannot call a C function pointer or convert a closure to C function pointer type.

how to call a function that takes a function pointer argument in Swift?

customCopyDescription needs to be a free function, not a method. When I copied your code into Xcode I got the error message only when customCopyDescription was inside a class, not otherwise.

Once placeholder return values are added and customCopyDescription is placed at file scope, the code compiles without a problem

Function pointer in swift

If you use func RunLoopSourceScheduleRoutine() as the callback
then it needs to be a global function, not an instance method.

If you define the callback as a closure then it needs to be marked
as a pure C callback:

let runLoopSourceScheduleRoutine: @convention(c) (UnsafeMutableRawPointer?, CFRunLoop?, CFRunLoopMode?) -> Void =
{ (info, rl, mode) in

let obj = Unmanaged<RunLoopSource>.fromOpaque(info!).takeUnretainedValue()
// ...
}

Alternatively, pass a closure expression to that the compiler
infers the type as a C callback:

var context = CFRunLoopSourceContext(version: 0, info: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) ,
retain: nil,
release: nil,
copyDescription: nil,
equal: nil,
hash: nil,
schedule: { (info, rl , mode) in

let obj = Unmanaged<RunLoopSource>.fromOpaque(info!).takeUnretainedValue()
// ...
}, cancel: nil,
perform: nil)

Note also that you have to call the method on obj, not on self.
I would recommend GCD instead of performSelector(), this allows
the compiler to check that the method is called with correct
arguments:

let obj = Unmanaged<RunLoopSource>.fromOpaque(info!).takeUnretainedValue()
let theContext = RunLoopContext(withSource: obj, andLoop: rl!)
DispatchQueue.main.async {
obj.myMethod(theContext)
}

Using Function pointer callback methods in Swift

As the error message says, you have to use @convention(c) in order to define the swift function or closure that is interoperable with other C functions. Try this:

typealias MethodHandler = @convention(c) (
_ msg_data_ptr : UnsafeMutablePointer<msg_data>?,
_ types: UnsafePointer<Int8>?,
_ argv : UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>?,
_ argc: Int32,
_ user_data: UnsafeMutablePointer<Int8>?
) -> Void

let handler: MethodHandler = { msg_data_ptr, types, argv, argc, user_data in
...
}

add_handler_new("handler", handler, nil, 0, 1)

How to initialize and use function pointer in Swift

To assign the closure to the property you have to remove the parentheses

self.funcPointer = self.func1

The subsequent error

self' used in method call 'func1' before all stored properties are initialized

can be fixed by declaring funcPointer implicit unwrapped optional

internal final var funcPointer: (() -> Void)!


Related Topics



Leave a reply



Submit