Guest User

Untitled

a guest
Aug 18th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 0.84 KB | None | 0 0
  1. use std::os::raw::c_void;
  2. use std::ptr::NonNull;
  3. type virErrorPtr = *const ();
  4.  
  5. type virErrorFunc = Option<unsafe extern "C" fn(userData: *mut c_void, error: virErrorPtr)>;
  6. extern "C" {
  7. fn virSetErrorFunc(userData: *mut c_void, handler: virErrorFunc);
  8. }
  9.  
  10. struct Error(virErrorPtr);
  11.  
  12. static mut HANDLER: Option<NonNull<Fn(Error)>> = None;
  13.  
  14. fn set_error_func<F: Fn(Error) + 'static>(f: F) {
  15. unsafe extern "C" fn callback<F: Fn(Error)>(userData: *mut c_void, error: virErrorPtr) {
  16. let f = userData as *const F;
  17. let wrapped_error = Error(error);
  18. (*f)(wrapped_error)
  19. }
  20. let data = Box::into_raw(Box::new(f));
  21. unsafe {
  22. HANDLER.take().map(|p| Box::from_raw(p.as_ptr())); //drop the old one
  23. HANDLER = Some(NonNull::new_unchecked(data));
  24. virSetErrorFunc(data as _, Some(callback::<F>))
  25. }
  26. }
  27.  
  28. fn main() {}
Add Comment
Please, Sign In to add comment