On Mon, Aug 14, 2023 at 07:55:15AM +0000, Tage Johansson wrote:
On 8/11/2023 2:00 PM, Eric Blake wrote:
> On Thu, Aug 03, 2023 at 03:36:05PM +0000, Tage Johansson wrote:
> > This commit creates basic Rust bindings in the rust directory.
> > The bindings are generated by generator/Rust.ml and
> > generator/RustSys.ml.
> > ---
> > --- /dev/null
> > +++ b/generator/RustSys.ml
> > +(** Print the struct for a closure. *)
> > +let print_closure_struct { cbname; cbargs } =
> > + pr "#[repr(C)]\n";
> > + pr "#[derive(Debug, Clone, Copy)]\n";
> > + pr "pub struct nbd_%s_callback {\n" cbname;
> > + pr " pub callback: \n";
> > + pr " Option<unsafe extern \"C\" fn(*mut c_void, %s)
-> c_int>,\n"
> > + (cbargs |> List.map cbarg_types |> List.flatten |> String.concat
", ");
> > + pr " pub user_data: *mut c_void,\n";
> > + pr " pub free: Option<unsafe extern \"C\" fn(*mut
c_void)>,\n";
> > + pr "}\n"
> Why is 'callback' an Option<> rather than a mandatory argument? I
get
> that 'free' must be an Option<> (because it corresponds to an
> OClosure, which is an optional callback), but 'callback' is a
> mandatory function pointer in the C API; why would it ever be
> acceptable to pass None instead of Some<function>?
It uses the "nullable pointer optimization"
<
https://doc.rust-lang.org/nomicon/ffi.html#the-nullable-pointer-optimizat...
which makes an Option<T> where T is a non nullable type be represented with
no extra space, and the None variant is represented by NULL.
Keep in mind that this is only the internal FFI bindings and the Option will
never be part of the public interface.
Ah, so if I'm understanding correctly, even though the libnbd API
requires a non-NULL function pointer, the problem is that the FFI code
can't in general tell which C functions with a function pointer
parameter allow NULL and which do not, so the conservative approach is
to document that _all_ FFI interactions with C functions use an
Option<T> nullable pointer when passing a function pointer across the
Rust->C boundary. It looks odd in relation to the libnbd
documentation of requiring non-NULL function, but is well-hidden
inside our internal code, and does not leak out to the public Rust
interface. That fills in some gaps for me; thanks.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization:
qemu.org |
libguestfs.org