rust-bindgen icon indicating copy to clipboard operation
rust-bindgen copied to clipboard

Finegrained control over bindings generation of class members

Open zopsicle opened this issue 5 months ago • 0 comments

As far as I understand, currently:

  • If bindings are generated for a class, bindings are also generated for all members of the class, as far as this is supported (e.g. no virtual methods).
  • This can be limited very coarsely using --generate. For example, --generate functions,types,vars,constructors,destructors will not generate bindings for any methods.
  • Base objects and fields can be hidden using --opaque-type.

But you can't allowlist or blocklist specific constructors, destructors, methods, and nested types.

A pattern that in my experience often comes up is where most members are suitable for direct bindgen, but a handful require custom glue code to be callable from Rust:

// library.h, third party
#include <string>

class Foo
{
public:
    Foo();
    enum Type { Static, Dynamic };
    void bar(Type);
    void baz(std::string);
};

// glue.cpp, my code
#include <library.h>

void Foo_baz(Foo* self, char const* ptr, std::size_t len)
{
    self->baz(std::string(ptr, len));
}
clang++ -c glue.cpp

# Do not generate bindings for Foo::baz, as it uses std::string which is too complex.
bindgen --allowlist-type Foo|Foo::Type \
        --allowlist-constructor Foo::Foo \
        --allowlist-method Foo::bar \
        --allowlist-function Foo_baz \
        glue.cpp

My current workaround is to just have bindings generated for all members, pass --no-recursive-allowlist, and define manual opaque types that are used in parameters and return types as needed, e.g. #[repr(C)] pub struct std_string([u8; 0]);. :P

zopsicle avatar Jul 12 '25 10:07 zopsicle