libffi-rs icon indicating copy to clipboard operation
libffi-rs copied to clipboard

Need some beginner documentation

Open torsteingrindvik opened this issue 4 years ago • 0 comments

Hi, thanks for this great crate.

I'm not sure how to store the intermediate types in a struct, could an example of this be added?

I'll give some context.

This works:

        let user_f = |s: &str| {
            println!("User got: {}", s);
        };

        let inner_f = |c_str| {
            let c_str = unsafe { CStr::from_ptr(c_str) };
            let str_slice = c_str.to_str().unwrap();
            user_f(str_slice);
        };
        let libffi_f = Closure1::new(&inner_f);

        let fun = libffi_f.code_ptr();

        MyStruct::new_with_callbacks(fun).unwrap();

However, I would like this user API to only need to specify the first closure. So something like:

        let user_f = |s: &str| {
            println!("User got: {}", s);
        };

        MyStruct::new_with_callbacks(user_f).unwrap();

This means I have to do the other work further down in the call-chain, and store all the functions somewhere.

My assumptions:

  • If user_f is dropped, the inner_f closure won't work since it uses that closure
  • If inner_f is dropped, libffi_f's reference is invalid
  • If libffi_f is dropped, any use of code_ptr() is invalid

Please correct me if I am wrong on any of those.

So my attempt is to create something like:

    struct MyStruct {
        user_f: Box<dyn Fn(String)>,
        inner_f: Box<dyn Fn(*const i8)>,
        libffi_f: Closure1<*const i8, ()>,
    }

But I am getting errors with needing named lifetime parameters on the pointers, and this struct references stuff in itself so I'm in a lot of trouble.

Could you help me out?

I will gladly contribute a PR with a test that shows the correct use if you teach me. So others can benefit as well.

torsteingrindvik avatar Feb 01 '21 22:02 torsteingrindvik