Eric Blake
2023-Aug-11 12:00 UTC
[Libguestfs] [libnbd PATCH v5 01/12] rust: create basic Rust bindings
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>? -- Eric Blake, Principal Software Engineer Red Hat, Inc. Virtualization: qemu.org | libguestfs.org
Tage Johansson
2023-Aug-14 07:55 UTC
[Libguestfs] [libnbd PATCH v5 01/12] rust: create basic Rust bindings
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. Best regards, Tage -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://listman.redhat.com/archives/libguestfs/attachments/20230814/027ad593/attachment.htm>