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-optimization> > 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 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://listman.redhat.com/mailman/listinfo/libguestfs