bindgen
repository·main·Indexed 26 days ago
https://github.com/rust-lang/rust-bindgenA tool for automatically generating Rust FFI bindings from C and C++ header files. It parses headers to produce equivalent Rust structs, enums, and function declarations, enabling interoperability between Rust and native C libraries. Includes a CLI for configuring binding generation, support for custom derives and attributes, and allowlisting/blocklisting of items.
What's inside bindgen
- rust-bindgen is a tool used to generate Rust FFI (Foreign Function Interface) bindings from C and C++ headers. It allows Rust code to interact with existing C/C++ libraries by automatically creating the necessary Rust declarations for types, functions, and constants.
Overview of rust-bindgen
mainbindgenis a tool that automatically generates Rust FFI (Foreign Function Interface) bindings to C and some C++ libraries. It parses C header files and produces equivalent Rust structs, enums, and function declarations, allowing Rust code to call into C libraries safely and easily.Generate Rust FFI bindings from C and C++ headers
mainUse
bindgento automatically generate Rust Foreign Function Interface (FFI) bindings for C and C++ libraries. This allows you to call C/C++ functions and use their types directly within Rust code by translating header files into equivalent Ruststructs andextern "C"blocks./* Input: C header (cool.h) */ typedef struct CoolStruct { int x; int y; } CoolStruct; void cool_function(int i, char c, CoolStruct* cs);/* Output: Generated Rust code */ #[repr(C)] pub struct CoolStruct { pub x: ::std::os::raw::c_int, pub y: ::std::os::raw::c_int, } extern "C" { pub fn cool_function(i: ::std::os::raw::c_int, c: ::std::os::raw::c_char, cs: *mut CoolStruct); }Build Clang from source for bindgen
mainIf your package manager does not provide Clang 9.0 or greater, you must build it from source. When building for
bindgen, follow these requirements:- Checkout and build
clang. - Checkout and build
clang-tools-extra.
Note: You do not need to checkout or build
compiler-rtorlibcxx.- Checkout and build
Generate bindings for C++ and Objective-C
mainWhile primarily focused on C,bindgensupports generating bindings for C++ headers and Objective-C headers.Treat a type as an opaque blob of bytes using C++ annotations
mainYou can mark a type as opaque directly in your C++ source code using a special comment annotation. This is useful for providing hints to
bindgenwithout changing the CLI command or the Rust builder logic./// <div rustbindgen opaque></div> class Foo { // ... };Replace a C or C++ definition with a Rust definition
mainThereplacesannotation only works for substituting one C/C++ type with another. If you need to completely replace a C or C++ definition with a custom Rust definition, you must use blocklisting to preventbindgenfrom generating bindings for the original type.Configure Rust target version for union support
mainTo use Rust's native
unionbuiltin, you must target Rust version 1.19 or higher (includingnightly). By default,bindgentargets the latest stable Rust. You can specify a target using the--rust-targetCLI flag or thebindgen::Builder::rust_target()method.Note: The
--unstable-rustoption is deprecated; use--rust-target nightlyinstead.Use allowlisting to limit generated bindings
mainBy default,bindgengenerates bindings for everything in the provided header files. To reduce noise or avoid unsupported C++ features, you can use allowlisting. When allowlisting rules are specified,bindgenonly generates bindings for types, functions, and global variables that match the rules, or are transitively used by a definition that matches them.Replace a C++ type with another type using the `replaces` annotation
mainUse the
replacesannotation within a comment block in your C or C++ header to substitute a complex type with a simpler one. This is useful when a structure is too complex forbindgento parse correctly (e.g., due to custom destructors preventing automatic trait derivation).When you use
replaces="TypeName",bindgenwill generate bindings forTypeNameusing the definition provided by the annotated type instead./** * <div rustbindgen replaces="nsTArray"></div> */ template<typename T> class nsTArray_Simple { T* mBuffer; public: ~nsTArray_Simple() {}; };Annotate types with `#[must_use]` using C annotations
mainYou can trigger the
#[must_use]attribute for a specific type directly in your C source code by using a specialrustbindgencomment block within the Doxygen-style comment of the type definition. Use themustusetypetag inside adiv./** <div rustbindgen mustusetype></div> */ struct ErrorType { // ... };Handle bindgen generated padding fields
mainbindgenmay generate padding fields named__bindgen_padding_Ndepending on the architecture and toolchain. To avoid manual initialization errors (as these fields may vary across architectures), use theDefaulttrait.Option 1: Enable automatic derivation Enable the
derive_defaultmethod when constructing yourbindgen::Builder.Option 2: Manual implementation Implement
Defaultfor the struct manually usingstd::mem::zeroed():impl Default for SRC_DATA { fn default() -> Self { unsafe { std::mem::zeroed() } } }Then, initialize your struct using the struct update syntax to automatically handle padding:
SRC_DATA { field_a: "foo", field_b: "bar", ..Default::default() }// Example of using struct update syntax with Default to handle padding SRC_DATA { field_a: "foo", field_b: "bar", ..Default::default() }