I have been struggling with a bug where some trait object containing a OnceCell worked fine, but when returned from a cdylib, caused STATUS_HEAP_CORRUPTION.
I proceeded to put on github a small project that replicated the issue as closely to the actual bug I had as possible while being minimal enough.
Then by playing a bit with it, I think I figured out the problem, or at least, a fix that works, but I would like to be sure that I understood properly.
Here is the example repo: https://github.com/Samuel-B-D/dyn-plugin-test/tree/bugged
On the bugged branch, running cargo run --example hello_world works just fine.
Running cargo build -p dyn-plugin-test | cargo run --example hello_world --features="dynamic" output
Successfully created App
Loaded handler constructor
Created Handler at: 0x2576da2f4e0
Raw handler ptr at: 0x2576da2f4e0
Dynamically created handler at: 0xcf1dbbf2a8
Re-boxed handler at: 0xcf1dbbf2a8
So it seems that the object get moved when crossing the ffi boundary?
Wrapping my trait object's raw pointer into a wrapper structure, Box::into_raw()ing that wrapper, sending that between the cdylib and retrieving it in a Box::from_raw, the contained pointer is indeed still the same, and the memory appear to be untouched and accessible, as shown in the fixed branch.
(I'm pretty new to FFI and dynamic libraries in Rust. Most of the information required to put that together come from https://michael-f-bryan.github.io/rust-ffi-guide/dynamic_loading.html, although in my case I'm dynamically loading a Rust library compiled as a C dynamic library, instead of a C++ one. The extra indirection doesn't seem to be required when loading a C/C++ library instead?)
My questions are the following:
- Did I properly understand the issue?
- Is this a correct / reliable way to handle this?