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


Reply via email to