Earlier quoted context omitted.
It can be from the perspective of the calling code. Roughly speaking: thread_local! { static CBQ: Option i32>>; } #[no_mangle] extern "C" fn qsort(array: *mut i32, val: usize, callback: impl FnMut(i32, i32) -> i32); pub fn rust_qsort(array : Vec , callback: impl FnMut(i32, i32) -> i32){ CBQ.replace(Box::new(callback)).unwrap_none(); unsafe { qsort(array.as_mut_ptr(), array.len(), &rust_qsort_callback); } CBQ.take().u…
This fails horribly if called recursively (or from a signal handler). You need something like: wrapped_qsort(/* array,callback */) { auto tmp = CBQ; CBQ = wrap(callback); qsort(array.ptr,array.len,cbq_callback); CBQ = tmp; /* pop old value from stack */ }
It won't fail recursively - while the second call is happening, the first will be stored on the stack (see the take and replace in the callback shim function)