#![allow(dead_code)]
use capi::sctypes::{LPCVOID, LPVOID};
type Opaque = LPCVOID;
#[repr(C)]
#[derive(Debug)]
pub struct NativeHandler {
handler: Opaque,
dtor: fn(param: Opaque),
}
impl Drop for NativeHandler {
fn drop(&mut self) {
if !self.handler.is_null() {
(self.dtor)(self.handler);
}
}
}
impl Default for NativeHandler {
fn default() -> Self {
NativeHandler { handler: ::std::ptr::null(), dtor: NativeHandler::drop_it::<i32> }
}
}
impl NativeHandler {
pub fn from<T>(handler: T) -> NativeHandler {
let boxed = Box::new(handler);
let ptr = Box::into_raw(boxed);
let dtor = NativeHandler::drop_it::<T>;
return NativeHandler { handler: ptr as Opaque, dtor: dtor };
}
pub fn as_ptr(&self) -> LPCVOID {
self.handler as LPCVOID
}
pub fn as_mut_ptr(&self) -> LPVOID {
self.handler as LPVOID
}
pub fn as_ref<T>(&self) -> &T {
let pobj = self.handler as *const T;
let boxed = unsafe { &*pobj };
return boxed;
}
pub fn as_mut<T>(&mut self) -> &mut T {
let pobj = self.handler as *mut T;
let boxed = unsafe { &mut *pobj };
return boxed;
}
#[allow(clippy::mut_from_ref)]
pub fn get_data<T>(ptr: &LPVOID) -> &mut T {
assert!(!ptr.is_null());
let obj = *ptr as *mut T;
unsafe { &mut *obj}
}
fn drop_it<T>(param: Opaque) {
let pobj = param as *mut T;
if !pobj.is_null() {
unsafe { Box::from_raw(pobj) };
}
}
}
#[cfg(test)]
mod test {
use super::NativeHandler;
struct Handler {
pub i: i32,
}
impl Drop for Handler {
fn drop(&mut self) {
println!("Handler::drop");
}
}
#[test]
fn test1() {
{
println!("\ncreate");
let h = Handler { i: 7 };
let p = NativeHandler::from(h);
println!("handler i {:?}", p.as_ref::<Handler>().i);
println!("quit");
}
println!("done.");
}
}