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" 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