On Fri, Sep 27, 2024 at 9:36 PM Stefan Hajnoczi <stefa...@gmail.com> wrote: > > On Mon, 1 Jul 2024 at 11:02, Paolo Bonzini <pbonz...@redhat.com> wrote: > > +/// A type for which there is a canonical representation as a C datum. > > +pub trait CloneToForeign { > > + /// The representation of `Self` as a C datum. Typically a > > + /// `struct`, though there are exceptions for example `c_char` > > + /// for strings, since C strings are of `char *` type). > > + type Foreign; > > + > > + /// Free the C datum pointed to by `p`. > > + /// > > + /// # Safety > > + /// > > + /// `p` must be `NULL` or point to valid data. > > + unsafe fn free_foreign(p: *mut Self::Foreign); > > + > > + /// Convert a native Rust object to a foreign C struct, copying > > + /// everything pointed to by `self` (same as `to_glib_full` in > > `glib-rs`) > > + fn clone_to_foreign(&self) -> OwnedPointer<Self>; > > I expected the return type to be OwnedPointer<Self::Foreign>. Is this a typo?
Kevin noticed the same. I'd have to check if I am missing something but it seems to be just tunnel vision. > Also, why is the return type OwnedPointer<T> instead of just T? I > guess it's common to want a heap-allocated value here so you decided > to hard-code OwnedPointer<>, but I'm not sure. Because at this point it looks like the most important conversion is to have a clone (meaning its lifetime is independent of the copy) and a value that is not movable (moves can be unpredictable and then usage in C is messy). The main example is creating a QEMU Error from something that implements the Rust std::error::Error trait. Actually I have written extra code that _borrows_ into a foreign object (so a CStr can be used as a *const c_char for as long as the CStr is alive), but I didn't really have a user and wrote it only to validate the concept. Paolo