FFI Destruct
Generates destructors for structures that contain raw pointers in the FFI.
About
The Destruct derive macro will implement Drop trait and free(drop) memory for structures containing raw pointers.
It may be a common procedure for FFI structure memory operations.
Supported types
Both *const and *mut are acceptable.
But currently, only single-level pointers are supported.
* c_char: c-style string, using std::ffi::CString::from_raw() to handle std::ffi::CString::into_raw()
* <T>: Using std::boxed::Box::from_raw() to handle std::boxed::Box::into_raw()
Example
Provides a structure with several raw pointers that need to be dropped manually.
use ffi_destruct::{extern_c_destructor, Destruct};
#[derive(Destruct)]
pub struct Structure {
c_string: *const c_char,
#[nullable]
c_string_nullable: *mut c_char,
other: *mut MyStruct,
#[nullable]
other_nullable: *mut MyStruct,
normal_int: u8,
normal_string: String,
}
extern_c_destructor!(Structure);
fn test_struct() {
let my_struct = Structure {
c_string: CString::new("Hello").unwrap().into_raw(),
c_string_nullable: std::ptr::null_mut(),
other: Box::into_raw(Box::new(MyStruct {
field: CString::new("Hello").unwrap().into_raw(),
})),
other_nullable: std::ptr::null_mut(),
};
let my_struct_ptr = Box::into_raw(Box::new(my_struct));
unsafe {
destruct_structure(my_struct_ptr);
}
}
After expanding the macro:
impl ::std::ops::Drop for Structure {
fn drop(&mut self) {
unsafe {
let _ = ::std::ffi::CString::from_raw(
self.c_string as *mut ::std::ffi::c_char,
);
if !self.c_string_nullable.is_null() {
let _ = ::std::ffi::CString::from_raw(
self.c_string_nullable as *mut ::std::ffi::c_char,
);
}
let _ = ::std::boxed::Box::from_raw(self.other as *mut TestA);
if !self.other_nullable.is_null() {
let _ = ::std::boxed::Box::from_raw(self.other_nullable as *mut TestA);
}
}
}
}
#[no_mangle]
pub unsafe extern "C" fn destruct_structure(ptr: *mut Structure) {
if ptr.is_null() {
return;
}
let _ = ::std::boxed::Box::from_raw(ptr);
}