I am working on an ffi crate and realized I can target a fairly old rust toolchain with little effort.
However, I need to replace this pattern:
let mut mem: Box<MaybeUninit<sys::c_struct>> = Box::new_uninit();
// initialize in C
let mem: Box<sys::c_struct> = unsafe { mem.assume_init() };
let inner: *mut sys::c_struct= Box::into_raw(mem);
Then of course, dropped with Box::from_raw
I think it could be replaced with just the following:
let mut mem: Box<MaybeUninit<sys::c_struct >> = Box::new(MaybeUninit::uninit());
let inner: *mut sys::c_struct = Box::into_raw(mem) as *mut sys::c_struct;
Is this alright to do, or are there better ways?
Thanks
Assuming the struct is small enough that it isn’t an issue for it to be on the stack temporarily, it should be equivalent to the original.
You could also std::alloc::alloc() the memory directly, without getting it from Box. It’s fine to convert such a pointer into Box<T> as long as the Layout used for allocation matches the layout of T (docs).
Don't forget to check for a null pointer indicating allocation failure! Box::new() will abort or panic but alloc() will just return null.
(I should perhaps have mentioned this in my previous post, too, but seeing the full line written out reminded me that they are not perfect substitutes in this way.)