Hello !
I am trying to make my Rust library interact with C, and I ran into an weird case.
I have the following rust code :
struct Caller<F: Fn()> {
function: F,
}
impl<F: Fn()> Caller<F> {
fn call(&self) {
(self.function)()
}
}
And my goal is to expose the Caller
struct to C : but
This code fails to compile because extern "C" fn()
does not implement Fn()
type Callback = extern "C" fn();
#[no_mangle]
extern "C" fn create_caller(function: Callback) -> *mut Caller<Callback> {
Box::leak(Box::new(Caller { function }))
}
And this one warns me that Caller<impl Fn()>
is not ffi-safe
type Callback = extern "C" fn();
#[no_mangle]
extern "C" fn create_caller(function: Callback) -> *mut Caller<impl Fn()> {
Box::leak(Box::new(Caller {
function: move || function(),
}))
}
Is the second version correct, despite the warning? Or is there a third, better way to do ?
s3bk
December 6, 2020, 6:58pm
2
Why not use
type Callback = extern "C" fn();
struct Caller {
function: Callback,
}
I don't think generics are needed?
Well Caller
is a bit more complex in reality, but the main reason it that it is used by Rust code, and it might make sense to create it with a closure for example.
Basically I am trying to make a C interface out of some pre-existing Rust code, and Caller
is a part of it.
Would something like this work?
The Caller
here could be a different type from the Caller
in your original code, and you can provide conversions between them.
This works like a charm, thanks !
1 Like
arnaudgolfouse:
Well Caller
is a bit more complex in reality, but the main reason it that it is used by Rust code, and it might make sense to create it with a closure for example.
Basically I am trying to make a C interface out of some pre-existing Rust code, and Caller
is a part of it.
A while back I did a write up on passing closures to native code. It might help explain why @RustyYato 's answer works and provide an alternative implementation without the double-indirection.
Every now and then when using native libraries from Rust you’ll be asked to pass a callback across the FFI boundary. The reasons are varied, but often this might be done to notify the caller when “interesting” things happen, for injecting logic (see...
1 Like
system
Closed
March 7, 2021, 2:44am
7
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.