core_utils_rs/
trampoline.rs1use 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}