getditto/safer_ffi

ReprC Box of dyn object

Closed this issue · 2 comments

The following example does not compile:

use safer_ffi::prelude::*;

#[ffi_export]
fn foobar(_: Option<repr_c::Box<dyn FooBar>>) {
    todo!()
}

It complains that dyn FooBar is not Sized but I fixed that with a quick hack, just adding ?Sized to a few places.

This error remains:

the trait `ReprC` is not implemented for `(dyn FooBar + 'static)`

Could this work eventually or is there some limitation I haven't think of?

Could this work eventually or is there some limitation I haven't think of?

This is #47: the layout of a fat pointer is not guaranteed, let alone FFI-safe; in the very near future (once #47 is implemented) it will be possible to write something along the lines of:

#[safer_ffi::repr(C)]
trait FooBar {
    fn method (self: &'_ mut Self, arg: Arg)
      -> R
    ;
}

#[ffi_export]
fn foobar (_: Option<c::Box<dyn FooBar>>)
{}

where c::Box<dyn FooBar + 'lt> would be an alias for CBoxDynFooBar<'lt>, which would be a manually laid out fat pointer that would enable the FFI interop:

//! generated bye the annotation on `trait FooBar`'s definition

#[safer_ffi::repr(C)]
struct CBoxDynFooBar<'lt> {
    ptr: ptr::NonNull<()>,
    vtable: &'lt FooBarVTable,
}

#[safer_ffi::repr(C)]
struct FooBarVTable {
    drop_boxed: unsafe extern "C" fn(ptr::NonNull<()>),
    method: unsafe extern "C" fn(ptr::NonNull<()>, arg: <Arg as ReprC>::CType) -> <Ret as ReprC>::CType,
}

Closing as a "duplicate" of #47