archimedes
archimedes

Reputation: 87

How to properly pass a callback-function from swift to c++?

I am trying to pass a callback-function from swift-code to c++ code. I am using the current version of Xcode. It works for simple variables, but not for functions so far:

cpp-class.cpp:

bool * swiftvar;

void register_var(bool * varpntr){
    swiftvar = varpntr;
    cout<<"registered"<<endl;
}

void switch_var(){
    *swiftvar = !(*swiftvar);
    cout<<"switched"<<endl;
}

cpp-class.hpp:

#ifdef __cplusplus
extern "C"{
#endif

    void register_var(bool *);
    void switch_var();

#ifdef __cplusplus
}
#endif

and in swift:

register_var(&testbool)
print(testbool)
switch_var()
print(testbool)

If i try the same for functions (which should be that simple in the current swift version as far as I know), I get errors. So how do I have to pass the function pointer in swift? All methods I found were causing errors. As i read, the old way of defining an UnsafeMutablePointer object an so on became obsolete, but how does it work now? I expect something like:

cpp-class.cpp:

void run_func(void * funcpntr()){
    (*funcpntr)();
}

cpp-class.hpp:

void run_func(void *);

(swift-pseudo-code):

run_func(testfunc())

Or is there even a better solution to run swift-functions from wrapped cpp-code?

Any help would be really appreciated. Thanks in advance

Upvotes: 3

Views: 1803

Answers (2)

OOPer
OOPer

Reputation: 47876

First of all, you need to declare the function type properly in .cpp/.hpp .

.cpp:

void run_func(void (* funcpntr)()) {
    (*funcpntr)();
}

.hpp:

void run_func(void (* funcpntr)());

(You can omit the latter funcpntr as shown in Jarod42's answer. And this needs to be enclosed in extern "C" {...} as shown in the first "cpp-class.hpp:".)

And Swift side:

Function definition:

//This needs to be a toplevel function, which means it cannot be a method.
func test_func() {
    //...
}

To pass it to run_func():

    run_func(test_func)

Or you can pass a closure to run_func:

    //This closure cannot have captured variables.
    run_func {
        //...
    }

Upvotes: 2

Jarod42
Jarod42

Reputation: 217225

The signature would be

void run_func(void (*)()); // Declaration

// Definition
void run_func(void (*funcpntr)()) {
    (*funcpntr)();
}

And usage

void testfunc(); 
run_func(&testfunc);

Upvotes: 0

Related Questions