#How to call a Rust function in a FFI callback?

17 messages · Page 1 of 1 (latest)

main sky
#
extern "C" {
    fn some_cfunc(callback: unsafe extern "C" fn());
}
fn some_func(callback: fn()) {
    extern "C" fn cb() {
        callback();
    }
    unsafe { some_cfunc(cb) };
}

I want to create a rust wrapper of the some_cfunc function in a C library and accept a rust callback. However the example is not working:

can't capture dynamic environment in a fn item
use the `|| { ... }` closure form instead (rustc E0434)

And wrap it with closure seem doesn't help....
How should I achieve that? Do I have to store the rust callback someway?

#

Yeah, you'll have to do this the C way.

#

Pass not only the callback pointer, but the data it needs to C

#

and have C call the callback with the data

main sky
#
extern "C" {
    fn some_cfunc(cb: unsafe extern "C" fn(), callback: fn());
}
fn some_func(callback: fn()) {
    extern "C" fn cb(callback: fn()) {
        callback();
    }
    unsafe { some_cfunc(cb, callback) };
}
#

If I'm unable to modify the C function, can I achieve it?

#

that depends on what the C function does and how you use it

#

The C function stores the callback, and later call it if something happened (done by other c function call)

#

if you don't need to support arbitrary fn pointers and instead using functions, this is easy

#

oh hum no I misremembered, there's no trait for plain function types

#

sad

main sky
#

Yes

#

Is there any way to differentiate the calls?

#

No
basicially this model:

void some_cfunc(int (*cb)()) {
  // store it..
}
void another_cfunc() {
  while (nothing_specially_happenned) {
    wait_until_a_event();
    cb();
  }
}
#

Then I think you just have to make the functions extern C in the first place