Regarding plugins: ABI of `dyn Trait` is unstable and using it across FFI boundary might be UB
ruifengx opened this issue · 0 comments
According to your own article (I believe), ABI for dyn Trait
objects is unstable, therefore the following use in this guide might be UB:
#[macro_export]
macro_rules! declare_plugin {
($plugin_type:ty, $constructor:path) => {
#[no_mangle]
pub extern "C" fn _plugin_create() -> *mut $crate::Plugin {
// make sure the constructor is the correct type.
let constructor: fn() -> $plugin_type = $constructor;
let object = constructor();
let boxed: Box<$crate::Plugin> = Box::new(object);
Box::into_raw(boxed)
}
};
}
Note the use of *mut $crate::Plugin
as the return type. In Rust 2018/2021, it should be *mut dyn $crate::Plugin
because Plugin
is a trait (instead of a type). And if the layout of trait objects were to change for building the plugin and the host program (though I doubt if this would ever happen), this would result in UB.
For solutions, it seems that abi_stable::sabi_trait
could be a candidate, but it looks ad-hoc and pulls in a non-trivial amount of dependencies. Another way would be to just use the "manual vtable" approach mentioned in your blog, which requires some boilerplate, but looks good otherwise.