I've been fiddling with some FFI with a Ruby project and I'm curious if this is the idiomatic way of printing/interacting with a value behind a raw pointer without dropping it.
#[no_mangle]
pub extern "C" fn sql_debug_query(query: *mut Query) {
let query = unsafe { Box::from_raw(query) };
println!("{:?}", query);
std::mem::forget(query); // this is required so the Box destructor isn't called, right?
}
I have a method to create a query that uses Box::into_raw(Box::new(query))
, and a complementary method to free a query that just does unsafe { Box::from_raw(query); }
. My question - is this (Box::from_raw / ... / std::mem::forget
) the correct/community-accepted method of inspecting a value behind a raw pointer? Is there any more concise way to express this, something like query.box_borrow_raw
that won't drop the Box when it goes out of scope? Should my fn accept *mut *mut Query
instead?
Thanks for any advice!
You can just reborrow it:
let query = unsafe { &*query };
println!("{:?}", query);
Edit: that function should be marked unsafe
though
4 Likes
To add to @SkiFire13 's answer:
- If your function can't free the memory that
query
points to, then it doesn't own that memory. So you want a reference, not an owned value like Box
.
- Your function leads to undefined behavior if a null, unaligned, or dangling pointer is passed in. Because null pointers can be constructed in safe code, you need to mark your function as
unsafe
and document that it has a safety invariant that the compiler can't check.
2 Likes
It seems like users.rust-lang.org is a better fit for this thread (internals.rust-lang.org is for the development of Rust (the language) and associated tooling (e.g., the rustc compiler)).
7 Likes
Ah! I wondered why I couldn’t find any non-internal tags and why I had to register an account to post, didn’t even think to check the URL.
Thanks all for the help anyways, I’ll use the correct forum next time 
1 Like