Reputation: 2127
I've defined a way to pass my Rust object to C++ so it can call this Rust object back:
extern "C" {
pub fn zlmedia_set_parent(zl_media: *mut ZLInstance, parent: Box<ZLMedia>);
}
pub fn new_boxed(url: &str) -> Box<ZLMedia> {
let c_url = CString::new(url).expect("CString::new failed");
let p = Box::new(ZLMedia {
zl_media: unsafe { zlmedia_new(c_url.into_raw()) },
url: url.to_string(),
});
unsafe {
zlmedia_set_parent(p.as_ref().zl_media, p);
}
p
}
The problem is that I can't pass the Box
to C++ because I move it here:
unsafe {
zlmedia_set_parent(p.as_ref().zl_media, p);
}
How can I pass a Box
to itself to C++ and still return it in the new
? I don't really need to move it, because it goes to a C++ function.
Upvotes: 4
Views: 236
Reputation: 58695
If you want the ZLMedia
to be owned by the Rust code then you can pass a pointer to it rather then the box itself.
use std::borrow::Borrow as _;
extern "C" {
pub fn zlmedia_set_parent(zl_media: *mut ZLInstance, parent: *const ZLMedia);
}
pub fn new_boxed(url: &str) -> Box<ZLMedia> {
let c_url = CString::new(url).expect("CString::new failed");
let p = Box::new(ZLMedia {
zl_media: unsafe { zlmedia_new(c_url.into_raw()) },
url: url.to_string(),
});
unsafe {
zlmedia_set_parent(p.as_ref().zl_media, p.borrow() as *const ZLMedia);
}
p
}
If the C++ code dereferences the pointer after the box is dropped, it will trigger Undefined Behaviour. If the C++ code tries to free the pointer then it's also UB. It's up to you to make sure that these things don't happen.
Upvotes: 1