mozilla / cbindgen

A project for generating C bindings from Rust code
Mozilla Public License 2.0
2.27k stars 294 forks source link

Function parameter annotations #982

Open RossSmyth opened 5 days ago

RossSmyth commented 5 days ago

From what I can tell from the docs, there is no way to add prefixes to function parameters. I think it would be useful to be able to do so. My motivating example is Windows SAL

https://learn.microsoft.com/en-us/cpp/code-quality/understanding-sal?view=msvc-170

To clarify to C++ consumers what the Rust code expects. Out pointers, strings vs pointers, optional parameters, and others. So that I can transform a Rust decl like this:

#[must_use]
pub unsafe extern "C" fn init(
    obj_out: *mut *mut SomeThing,
    file: Option<NonNull<c_char>>,
    handle: RawHandle,
) -> Status

into this C++ decl

_Check_return_ Status init(
    _Outptr_ SomeThing **obj_out,
    _In_opt_z_ char *file,
    _In_ HANDLE handle
);

What the annotation would look like, I'm not sure. Maybe something like

/// cbindgen:param-prefix = [_Outptr_, _In_opt_z_, _In_]

and to a lesser extent for struct decls, though it's not as important to me.

#[repr(C)]
pub struct SomeThing {
    name: *const c_char,
    len: usize,
    serial: *const c_char,
}

->

struct SomeThing {
    // Null-terminated string
    _Field_z_  const char *name;

    // Not null-terminated, the length is in the preceding field
    uintptr_t len;
    _Field_size_(len) const char *serial;
};