I'm new to rust and I want to implement a rust lib called by a c program.
The problem is how to check if the raw pointer passed in function parse is valid? because it may be dropped already by free_parser, and it will cause crash in this case.
#[no_mangle]
pub extern fn create_parser() -> *mut Parser {
// let parser = create a parser in some way ...
let raw_pointer = unsafe { transmute(Box::new(parser)) };
raw_pointer
}
#[no_mangle]
pub extern fn parse(ptr: *mut Parser, text: *const c_char) -> *mut c_char {
let mut parser = unsafe { &mut *ptr };
// how to check the parser here before use it?
// to do something with the parser & text, and finally return result as c_char
//...
}
#[no_mangle]
pub extern fn free_parser(ptr: *mut Parser) {
if !ptr.is_null() {
let _: Box<Parser> = unsafe { transmute(ptr) };
}
}
There is no way to know if the pointer has been freed. The caller of your functions must ensure not to call parse if free_parser has been called.
Note that transmuting Box is not safe, as its memory representation is not specified. You must use into_raw() to get the raw pointer and use from_raw to construct the box back when you want to drop it.
No need to pass a pointer if it can't be read in other code. Just use some ID and store the structure in either static or thread local. (Few alternate ways possible too.)