On 9/27/24 22:26, Paolo Bonzini wrote:
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.
It's been a while and probably everybody has forgotten about this.
Anyhow, the main reason why this returns for example
OwnedPointer<String> instead of OwnedPointer<c_char>, is that it tracks
whether the pointer can be NULL or not. A possibly-NULL pointer will be
OwnedPointer<Option<String>>; if the pointer is certainly non-NULL,
instead, it will be OwnedPointer<String>. So you can express
nullability in functions that accept an OwnedPointer<>.
Secondarily, it makes it possible to implement
OwnedPointer::into_native(). That is, it makes it easier to do the
opposite conversion once you're done with the foreign representation:
// s is a String
foreign_ptr = s.clone_to_foreign();
call_c_function(foreign_ptr);
*s = foreign_ptr.into_native();
as opposed to
foreign_ptr = s.clone_to_foreign();
call_c_function(foreign_ptr);
*s = String::from_foreign(foreign_ptr);
By the way, I have now extracted this library and published it on
crates.io with the name "foreign".
Paolo