core_utils_rs/
trampoline.rs

1use std::{ffi::c_void, ptr};
2
3#[repr(transparent)]
4pub struct TrampolineRefcon(*mut c_void);
5
6#[repr(transparent)]
7pub struct TrampolineLeftCallback<Ret = (), Param = TrampolineRefcon>(
8    extern "C" fn(TrampolineRefcon, Param) -> Ret,
9);
10#[repr(transparent)]
11pub struct TrampolineRightCallback<Ret = (), Param = TrampolineRefcon>(
12    extern "C" fn(Param, TrampolineRefcon) -> Ret,
13);
14
15pub fn create_left_trampoline<'a, Ret, Param, F: 'a + Send + FnOnce(Param) -> Ret>(
16    wrapped_closure: F,
17) -> (TrampolineLeftCallback<Ret, Param>, TrampolineRefcon) {
18    pub extern "C" fn caller<Ret, Param, F>(closure_ptr: TrampolineRefcon, param: Param) -> Ret
19    where
20        F: FnOnce(Param) -> Ret,
21    {
22        println!("caller");
23        unsafe {
24            let closure: F = ptr::read(closure_ptr.0.cast());
25            closure(param)
26        }
27    }
28    (
29        TrampolineLeftCallback(caller::<Ret, Param, F>),
30        TrampolineRefcon(Box::into_raw(Box::new(wrapped_closure)).cast()),
31    )
32}
33
34pub fn create_right_trampoline<'a, Ret, Param, F: 'a + Send + FnOnce(Param) -> Ret>(
35    wrapped_closure: F,
36) -> (TrampolineRightCallback<Ret, Param>, TrampolineRefcon) {
37    pub extern "C" fn caller<Ret, Param, F>(param: Param, closure_ptr: TrampolineRefcon) -> Ret
38    where
39        F: FnOnce(Param) -> Ret,
40    {
41        println!("caller");
42        unsafe {
43            let closure: F = ptr::read(closure_ptr.0.cast());
44            closure(param)
45        }
46    }
47    (
48        TrampolineRightCallback(caller::<Ret, Param, F>),
49        TrampolineRefcon(Box::into_raw(Box::new(wrapped_closure)).cast()),
50    )
51}