The bindgen User Guide
Description: `bindgen` automatically generates Rust FFI bindings to C and C++ libraries.

## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# Introduction

`bindgen` automatically generates Rust FFI bindings to C and C++ libraries.

For example, given the C header `cool.h`:

    typedef struct CoolStruct {
        int x;
        int y;
    } CoolStruct;

    void cool_function(int i, char c, CoolStruct* cs);

`bindgen` produces Rust FFI code allowing you to call into the `cool` library’s functions and use its types:

    #![allow(unused)]
    fn main() {
    /* automatically generated by rust-bindgen 0.99.9 */

    #[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);
    }
    }

# Requirements

This page lists the requirements for running `bindgen` and how to get them.

## Clang

`bindgen` leverages `libclang` to preprocess, parse, and type check C and C++ header files.

It is required to use Clang 9.0 or greater.

### Installing Clang

#### Windows

If you use winget:

    winget install LLVM.LLVM

Alternatively, you can download and install the official pre-built binary from LLVM download page.

You will also need to set `LIBCLANG_PATH` as an environment variable pointing to the `bin` directory of your LLVM install. For example, if you installed LLVM to `D:\programs\LLVM`, then you’d set the value to be `D:\programs\LLVM\bin`.

Alternatively, for Mingw64, you can install clang via

    pacman -S  mingw64/mingw-w64-x86_64-clang

#### macOS

If you use Homebrew:

    $ brew install llvm

If you use MacPorts:

    $ port install clang

#### Debian-based Linuxes

    # apt install libclang-dev

If you want to use the function `bindgen::Builder::dump_preprocessed_input`, then you also need the package `clang`.

#### Arch

    # pacman -S clang

#### Fedora

    # dnf install clang-devel

#### OpenBSD

    # pkg_add llvm

Add `export LIBCLANG_PATH=/usr/local/lib` to your profile.

#### From source

If your package manager doesn’t yet offer Clang 9.0, you’ll need to build from source. For that, follow the instructions here.

Those instructions list optional steps. For `bindgen`:

- Checkout and build clang
- Checkout and build `clang-tools-extra`
- You do not need to checkout or build compiler-rt
- You do not need to checkout or build libcxx

# Library Usage with `build.rs`

💡 This is the recommended way to use `bindgen`. 💡

Often times C and C++ headers will have platform- and architecture-specific `#ifdef`s that affect the shape of the Rust FFI bindings we need to create to interface Rust code with the outside world. By using `bindgen` as a library inside your `build.rs`, you can generate bindings for the current target on-the-fly. Otherwise, you would need to generate and maintain `x86_64-unknown-linux-gnu-bindings.rs`, `x86_64-apple-darwin-bindings.rs`, etc… separate bindings files for each of your supported targets, which can be a huge pain. The downside is that everyone building your crate also needs `libclang` available to run `bindgen`.

## Library API Documentation

📚 There is complete API reference documentation on docs.rs 📚

## Tutorial

The next section contains a detailed, step-by-step tutorial for using `bindgen` as a library inside `build.rs`.

# Tutorial

The following tutorial is adapted from this blog post.

What follows is a whirlwind introductory tutorial to using `bindgen` from inside `build.rs`. We’ll generate bindings to `bzip2` (which is available on most systems) on-the-fly.

TL;DR? The full tutorial code is available here.

# Add `bindgen` as a Build Dependency

First we need to declare a build-time dependency on `bindgen` by adding it to the `[build-dependencies]` section of our crate’s `Cargo.toml` file.

Please always use the latest version of `bindgen`, as it has the most fixes and best compatibility. You can always check the latest version at the bindgen page in crates.io.

    [build-dependencies]
    bindgen = "0.71.0"

> ⚠️ Warning

> `bindgen` needs to be added to the `[build-dependencies]` section, not the normal `[dependencies]` section. If you add it as a regular dependency, you will get errors like the following: `error[E0463]: can't find crate for `bindgen``

# Create a `wrapper.h` Header

The `wrapper.h` file will include all the various headers containing declarations of structs and functions we would like bindings for. In the particular case of `bzip2`, this is pretty easy since the entire public API is contained in a single header. For a project like SpiderMonkey, where the public API is split across multiple header files and grouped by functionality, we’d want to include all those headers we want to bind to in this single `wrapper.h` entry point for `bindgen`.

Here is our `wrapper.h`:

    #include <bzlib.h>

This is also where we would add any replacement types, if we were using some.

# Create a `build.rs` File

We create a `build.rs` file in our crate’s root. Cargo will pick up on the existence of this file, then compile and execute it before the rest of the crate is built. This can be used to generate code at compile time. And of course in our case, we will be generating Rust FFI bindings to `bzip2` at compile time. The resulting bindings will be written to `$OUT_DIR/bindings.rs` where `$OUT_DIR` is chosen by `cargo` and is something like `./target/debug/build/bindgen-tutorial-bzip2-sys-afc7747d7eafd720/out/`.

Note that the associated shared object to `bz2` is `libbz2.so`. In general, a `lib<name>.so` should be referenced in the build file by `<name>`.

    use std::env;
    use std::path::PathBuf;

    fn main() {
        // Tell cargo to look for shared libraries in the specified directory
        println!("cargo:rustc-link-search=/path/to/lib");

        // Tell cargo to tell rustc to link the system bzip2
        // shared library.
        println!("cargo:rustc-link-lib=bz2");

        // The bindgen::Builder is the main entry point
        // to bindgen, and lets you build up options for
        // the resulting bindings.
        let bindings = bindgen::Builder::default()
            // The input header we would like to generate
            // bindings for.
            .header("wrapper.h")
            // Tell cargo to invalidate the built crate whenever any of the
            // included header files changed.
            .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
            // Finish the builder and generate the bindings.
            .generate()
            // Unwrap the Result and panic on failure.
            .expect("Unable to generate bindings");

        // Write the bindings to the $OUT_DIR/bindings.rs file.
        let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
        bindings
            .write_to_file(out_path.join("bindings.rs"))
            .expect("Couldn't write bindings!");
    }

Now, when we run `cargo build`, our bindings to `bzip2` are generated on the fly!

There’s more info about `build.rs` files in the Cargo documentation.

# Include the Generated Bindings in `src/lib.rs`

We can use the `include!` macro to dump our generated bindings right into our crate’s main entry point, `src/lib.rs`:

    #![allow(non_upper_case_globals)]
    #![allow(non_camel_case_types)]
    #![allow(non_snake_case)]

    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

Because `bzip2`’s symbols do not follow Rust’s style conventions, we suppress a bunch of warnings with a few `#![allow(...)]` pragmas.

We can run `cargo build` again to check that the bindings themselves compile:

    $ cargo build
       Compiling bindgen-tutorial-bzip2-sys v0.1.0
        Finished debug [unoptimized + debuginfo] target(s) in 62.8 secs

And we can run `cargo test` to verify that the layout, size, and alignment of our generated Rust FFI structs match what `bindgen` thinks they should be:

    $ cargo test
       Compiling bindgen-tutorial-bzip2-sys v0.1.0
        Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
         Running target/debug/deps/bzip2_sys-10413fc2af207810

    running 14 tests
    test bindgen_test_layout___darwin_pthread_handler_rec ... ok
    test bindgen_test_layout___sFILE ... ok
    test bindgen_test_layout___sbuf ... ok
    test bindgen_test_layout__bindgen_ty_1 ... ok
    test bindgen_test_layout__bindgen_ty_2 ... ok
    test bindgen_test_layout__opaque_pthread_attr_t ... ok
    test bindgen_test_layout__opaque_pthread_cond_t ... ok
    test bindgen_test_layout__opaque_pthread_mutex_t ... ok
    test bindgen_test_layout__opaque_pthread_condattr_t ... ok
    test bindgen_test_layout__opaque_pthread_mutexattr_t ... ok
    test bindgen_test_layout__opaque_pthread_once_t ... ok
    test bindgen_test_layout__opaque_pthread_rwlock_t ... ok
    test bindgen_test_layout__opaque_pthread_rwlockattr_t ... ok
    test bindgen_test_layout__opaque_pthread_t ... ok

    test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured

       Doc-tests bindgen-tutorial-bzip2-sys

    running 0 tests

    test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

# Write a Sanity Test

Finally, to tie everything together, let’s write a sanity test that round trips some text through compression and decompression, and then asserts that it came back out the same as it went in. This is a little wordy using the raw FFI bindings, but hopefully we wouldn’t usually ask people to do this, we’d provide a nice Rust-y API on top of the raw FFI bindings for them. However, since this is for testing the bindings directly, our sanity test will use the bindings directly.

The test data I’m round tripping are some Futurama quotes I got off the internet and put in the `futurama-quotes.txt` file, which is read into a `&'static str` at compile time via the `include_str!("../futurama-quotes.txt")` macro invocation.

Without further ado, here is the test, which should be appended to the bottom of our `src/lib.rs` file:

    #![allow(unused)]
    fn main() {
    #[cfg(test)]
    mod tests {
        use super::*;
        use std::mem;

        #[test]
        fn round_trip_compression_decompression() {
            unsafe {
                let input = include_str!("../futurama-quotes.txt").as_bytes();
                let mut compressed_output: Vec<u8> = vec![0; input.len()];
                let mut decompressed_output: Vec<u8> = vec![0; input.len()];

                // Construct a compression stream.
                let mut stream: bz_stream = mem::zeroed();
                let result = BZ2_bzCompressInit(&mut stream as *mut _,
                                                1,   // 1 x 100000 block size
                                                4,   // verbosity (4 = most verbose)
                                                0);  // default work factor
                match result {
                    r if r == (BZ_CONFIG_ERROR as _) => panic!("BZ_CONFIG_ERROR"),
                    r if r == (BZ_PARAM_ERROR as _) => panic!("BZ_PARAM_ERROR"),
                    r if r == (BZ_MEM_ERROR as _) => panic!("BZ_MEM_ERROR"),
                    r if r == (BZ_OK as _) => {},
                    r => panic!("Unknown return value = {r}"),
                }

                // Compress `input` into `compressed_output`.
                stream.next_in = input.as_ptr() as *mut _;
                stream.avail_in = input.len() as _;
                stream.next_out = compressed_output.as_mut_ptr() as *mut _;
                stream.avail_out = compressed_output.len() as _;
                let result = BZ2_bzCompress(&mut stream as *mut _, BZ_FINISH as _);
                match result {
                    r if r == (BZ_RUN_OK as _) => panic!("BZ_RUN_OK"),
                    r if r == (BZ_FLUSH_OK as _) => panic!("BZ_FLUSH_OK"),
                    r if r == (BZ_FINISH_OK as _) => panic!("BZ_FINISH_OK"),
                    r if r == (BZ_SEQUENCE_ERROR as _) => panic!("BZ_SEQUENCE_ERROR"),
                    r if r == (BZ_STREAM_END as _) => {},
                    r => panic!("Unknown return value = {r}"),
                }

                // Finish the compression stream.
                let result = BZ2_bzCompressEnd(&mut stream as *mut _);
                match result {
                    r if r == (BZ_PARAM_ERROR as _) => panic!("BZ_PARAM_ERROR"),
                    r if r == (BZ_OK as _) => {},
                    r => panic!("Unknown return value = {r}"),
                }

                // Construct a decompression stream.
                let mut stream: bz_stream = mem::zeroed();
                let result = BZ2_bzDecompressInit(&mut stream as *mut _,
                                                  4,   // verbosity (4 = most verbose)
                                                  0);  // default small factor
                match result {
                    r if r == (BZ_CONFIG_ERROR as _) => panic!("BZ_CONFIG_ERROR"),
                    r if r == (BZ_PARAM_ERROR as _) => panic!("BZ_PARAM_ERROR"),
                    r if r == (BZ_MEM_ERROR as _) => panic!("BZ_MEM_ERROR"),
                    r if r == (BZ_OK as _) => {},
                    r => panic!("Unknown return value = {r}"),
                }

                // Decompress `compressed_output` into `decompressed_output`.
                stream.next_in = compressed_output.as_ptr() as *mut _;
                stream.avail_in = compressed_output.len() as _;
                stream.next_out = decompressed_output.as_mut_ptr() as *mut _;
                stream.avail_out = decompressed_output.len() as _;
                let result = BZ2_bzDecompress(&mut stream as *mut _);
                match result {
                    r if r == (BZ_PARAM_ERROR as _) => panic!("BZ_PARAM_ERROR"),
                    r if r == (BZ_DATA_ERROR as _) => panic!("BZ_DATA_ERROR"),
                    r if r == (BZ_DATA_ERROR_MAGIC as _) => panic!("BZ_DATA_ERROR"),
                    r if r == (BZ_MEM_ERROR as _) => panic!("BZ_MEM_ERROR"),
                    r if r == (BZ_OK as _) => panic!("BZ_OK"),
                    r if r == (BZ_STREAM_END as _) => {},
                    r => panic!("Unknown return value = {r}"),
                }

                // Close the decompression stream.
                let result = BZ2_bzDecompressEnd(&mut stream as *mut _);
                match result {
                    r if r == (BZ_PARAM_ERROR as _) => panic!("BZ_PARAM_ERROR"),
                    r if r == (BZ_OK as _) => {},
                    r => panic!("Unknown return value = {r}"),
                }

                assert_eq!(input, &decompressed_output[..]);
            }
        }
    }
    }

Now let’s run `cargo test` again and verify that everything is linking and binding properly!

    $ cargo test
       Compiling bindgen-tutorial-bzip2-sys v0.1.0
        Finished debug [unoptimized + debuginfo] target(s) in 0.54 secs
         Running target/debug/deps/bindgen_tutorial_bzip2_sys-1c5626bbc4401c3a

    running 15 tests
    test bindgen_test_layout___darwin_pthread_handler_rec ... ok
    test bindgen_test_layout___sFILE ... ok
    test bindgen_test_layout___sbuf ... ok
    test bindgen_test_layout__bindgen_ty_1 ... ok
    test bindgen_test_layout__bindgen_ty_2 ... ok
    test bindgen_test_layout__opaque_pthread_attr_t ... ok
    test bindgen_test_layout__opaque_pthread_cond_t ... ok
    test bindgen_test_layout__opaque_pthread_condattr_t ... ok
    test bindgen_test_layout__opaque_pthread_mutex_t ... ok
    test bindgen_test_layout__opaque_pthread_mutexattr_t ... ok
    test bindgen_test_layout__opaque_pthread_once_t ... ok
    test bindgen_test_layout__opaque_pthread_rwlock_t ... ok
    test bindgen_test_layout__opaque_pthread_rwlockattr_t ... ok
    test bindgen_test_layout__opaque_pthread_t ... ok
        block 1: crc = 0x47bfca17, combined CRC = 0x47bfca17, size = 2857
            bucket sorting ...
            depth      1 has   2849 unresolved strings
            depth      2 has   2702 unresolved strings
            depth      4 has   1508 unresolved strings
            depth      8 has    538 unresolved strings
            depth     16 has    148 unresolved strings
            depth     32 has      0 unresolved strings
            reconstructing block ...
          2857 in block, 2221 after MTF & 1-2 coding, 61+2 syms in use
          initial group 5, [0 .. 1], has 570 syms (25.7%)
          initial group 4, [2 .. 2], has 256 syms (11.5%)
          initial group 3, [3 .. 6], has 554 syms (24.9%)
          initial group 2, [7 .. 12], has 372 syms (16.7%)
          initial group 1, [13 .. 62], has 469 syms (21.1%)
          pass 1: size is 2743, grp uses are 13 6 15 0 11
          pass 2: size is 1216, grp uses are 13 7 15 0 10
          pass 3: size is 1214, grp uses are 13 8 14 0 10
          pass 4: size is 1213, grp uses are 13 9 13 0 10
          bytes: mapping 19, selectors 17, code lengths 79, codes 1213
        final combined CRC = 0x47bfca17

        [1: huff+mtf rt+rld {0x47bfca17, 0x47bfca17}]
        combined CRCs: stored = 0x47bfca17, computed = 0x47bfca17
    test tests::round_trip_compression_decompression ... ok

    test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured

       Doc-tests bindgen-tutorial-bzip2-sys

    running 0 tests

    test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

# Publish Your Crate!

That’s it! Now we can publish our crate on crates.io and we can write a nice, Rust-y API wrapping the raw FFI bindings in a safe interface. However, there is already a `bzip2-sys` crate providing raw FFI bindings, and there is already a `bzip2` crate providing a nice, safe, Rust-y API on top of the bindings, so we have nothing left to do here!

Check out the full code on Github!

# Bindings for non-system libraries

Now let’s suppose we want to generate bindings for a non-system library. We will be the same crate setup as the previous tutorial. First let’s create a new directory `hello` with two files inside it. A C source file `hello.c` containing

    int hello() {
        return 42;
    }

and a C header file `hello.h` containing

    int hello();

Given that the library has not been compiled yet, we need to modify the `build.rs` build script to compile the `hello.c` source file into a static library:

    use std::env;
    use std::path::PathBuf;

    fn main() {
        // This is the directory where the `c` library is located.
        let libdir_path = PathBuf::from("hello")
            // Canonicalize the path as `rustc-link-search` requires an absolute
            // path.
            .canonicalize()
            .expect("cannot canonicalize path");

        // This is the path to the `c` headers file.
        let headers_path = libdir_path.join("hello.h");
        let headers_path_str = headers_path.to_str().expect("Path is not a valid string");

        // This is the path to the intermediate object file for our library.
        let obj_path = libdir_path.join("hello.o");
        // This is the path to the static library file.
        let lib_path = libdir_path.join("libhello.a");

        // Tell cargo to look for shared libraries in the specified directory
        println!("cargo:rustc-link-search={}", libdir_path.to_str().unwrap());

        // Tell cargo to tell rustc to link our `hello` library. Cargo will
        // automatically know it must look for a `libhello.a` file.
        println!("cargo:rustc-link-lib=hello");

        // Run `clang` to compile the `hello.c` file into a `hello.o` object file.
        // Unwrap if it is not possible to spawn the process.
        if !std::process::Command::new("clang")
            .arg("-c")
            .arg("-o")
            .arg(&obj_path)
            .arg(libdir_path.join("hello.c"))
            .output()
            .expect("could not spawn `clang`")
            .status
            .success()
        {
            // Panic if the command was not successful.
            panic!("could not compile object file");
        }

        // Run `ar` to generate the `libhello.a` file from the `hello.o` file.
        // Unwrap if it is not possible to spawn the process.
        if !std::process::Command::new("ar")
            .arg("rcs")
            .arg(lib_path)
            .arg(obj_path)
            .output()
            .expect("could not spawn `ar`")
            .status
            .success()
        {
            // Panic if the command was not successful.
            panic!("could not emit library file");
        }

        // The bindgen::Builder is the main entry point
        // to bindgen, and lets you build up options for
        // the resulting bindings.
        let bindings = bindgen::Builder::default()
            // The input header we would like to generate
            // bindings for.
            .header(headers_path_str)
            // Tell cargo to invalidate the built crate whenever any of the
            // included header files changed.
            .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
            // Finish the builder and generate the bindings.
            .generate()
            // Unwrap the Result and panic on failure.
            .expect("Unable to generate bindings");

        // Write the bindings to the $OUT_DIR/bindings.rs file.
        let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings.rs");
        bindings
            .write_to_file(out_path)
            .expect("Couldn't write bindings!");
    }

# Command Line Usage

Install the `bindgen` executable with `cargo`:

    $ cargo install bindgen-cli

The `bindgen` executable is installed to `~/.cargo/bin`. You have to add that directory to your `$PATH` to use `bindgen`.

`bindgen` takes the path to an input C or C++ header file, and optionally an output file path for the generated bindings. If the output file path is not supplied, the bindings are printed to `stdout`.

If we wanted to generated Rust FFI bindings from a C header named `input.h` and put them in the `bindings.rs` file, we would invoke `bindgen` like this:

    $ bindgen input.h -o bindings.rs

For more details, pass the `--help` flag:

    $ bindgen --help

# Customizing the Generated Bindings

The translation of classes, structs, enums, and typedefs can be adjusted in a few ways:

1. By using the `bindgen::Builder`’s configuration methods, when using `bindgen` as a library.

2. By passing extra flags and options to the `bindgen` executable.

3. By adding an annotation comment to the C/C++ source code. Annotations are specially formatted HTML tags inside doxygen style comments:

   - For single line comments:

         /// <div rustbindgen></div>

   - For multi-line comments:

         /**
          * <div rustbindgen></div>
          */

We’ll leave the nitty-gritty details to the docs.rs API reference and `bindgen --help`, but provide higher level concept documentation here.

# Allowlisting

Allowlisting allows us to be precise about which type, function, and global variable definitions `bindgen` generates bindings for. By default, if we don’t specify any allowlisting rules, everything is considered allowlisted. This may not be desirable because of either

- the generated bindings contain a lot of extra definitions we don’t plan on using, or
- the header file contains C++ features for which Rust does not have a corresponding form (such as partial template specialization), and we would like to avoid these definitions

If we specify allowlisting rules, then `bindgen` will only generate bindings to types, functions, and global variables that match the allowlisting rules, or are transitively used by a definition that matches them.

### Library

- `bindgen::Builder::allowlist_type`
- `bindgen::Builder::allowlist_function`
- `bindgen::Builder::allowlist_var`
- `bindgen::Builder::allowlist_file`
- `bindgen::Builder::allowlist_item`

### Command Line

- `--allowlist-type <type>`
- `--allowlist-function <function>`
- `--allowlist-var <var>`
- `--allowlist-file <path>`
- `--allowlist-item <item>`

### Annotations

None.

# Blocklisting

If you need to provide your own custom translation of some type (for example, because you need to wrap one of its fields in an `UnsafeCell`), you can explicitly blocklist generation of its definition. Uses of the blocklisted type will still appear in other types’ definitions. (If you don’t want the type to appear in the bindings at all, make it opaque instead of blocklisting it.)

Blocklisted types are pessimistically assumed not to be able to `derive` any traits, which can transitively affect other types’ ability to `derive` traits or not.

The `blocklist-file` option also allows the blocklisting of all items from a particular path regex, for example to block all types defined in system headers that are transitively included.

### Library

- `bindgen::Builder::blocklist_file`
- `bindgen::Builder::blocklist_function`
- `bindgen::Builder::blocklist_item`
- `bindgen::Builder::blocklist_type`
- `bindgen::Builder::blocklist_var`

### Command Line

- `--blocklist-file <path>`
- `--blocklist-function <function>`
- `--blocklist-item <item>`
- `--blocklist-type <type>`
- `--blocklist-var <var>`

### Annotations

    /// <div rustbindgen hide></div>
    class Foo {
        // ...
    };

# Treating a Type as an Opaque Blob of Bytes

Sometimes a type definition is simply not translatable to Rust, for example it uses C++’s SFINAE for which Rust has no equivalent. In these cases, it is best to treat all occurrences of the type as an opaque blob of bytes with a size and alignment. `bindgen` will attempt to detect such cases and do this automatically, but other times it needs some explicit help from you.

### Library

- `bindgen::Builder::opaque_type`

### Command Line

- `--opaque-type <type>`

### Annotation

    /// <div rustbindgen opaque></div>
    class Foo {
        // ...
    };

# Replacing One Type with Another

The `replaces` annotation can be used to use a type as a replacement for other (presumably more complex) type. This is used in Stylo to generate bindings for structures that for multiple reasons are too complex for bindgen to understand.

For example, in a C++ header:

    /**
     * <div rustbindgen replaces="nsTArray"></div>
     */
    template<typename T>
    class nsTArray_Simple {
      T* mBuffer;
    public:
      // The existence of a destructor here prevents bindgen from deriving the Clone
      // trait via a simple memory copy.
      ~nsTArray_Simple() {};
    };

That way, after code generation, the bindings for the `nsTArray` type are the ones that would be generated for `nsTArray_Simple`.

Replacing is only available as an annotation. To replace a C or C++ definition with a Rust definition, use blocklisting.

# Preventing the Derivation of `Copy` and `Clone`

`bindgen` will attempt to derive the `Copy` and `Clone` traits on a best-effort basis. Sometimes, it might not understand that although adding `#[derive(Copy, Clone)]` to a translated type definition will compile, it still shouldn’t do that for reasons it can’t know. In these cases, the `nocopy` annotation can be used to prevent bindgen to autoderive the `Copy` and `Clone` traits for a type.

### Library

- `bindgen::Builder::no_copy`

### Command Line

- `--no-copy <regex>`

### Annotations

    /**
     * Although bindgen can't know, this struct is not safe to move because pthread
     * mutexes can't move in memory!
     *
     * <div rustbindgen nocopy></div>
     */
    struct MyMutexWrapper {
        pthread_mutex_t raw;
        // ...
    };

# Preventing the Derivation of `Debug`

`bindgen` will attempt to derive the `Debug` traits on a best-effort basis. Sometimes, it might not understand that although adding `#[derive(Debug)]` to a translated type definition will compile, it still shouldn’t do that for reasons it can’t know. In these cases, the `nodebug` annotation can be used to prevent bindgen to autoderive the `Debug` traits for a type.

### Library

- `bindgen::Builder::no_debug`

### Command Line

- `--no-debug <regex>`

### Annotations

    /**
     * Although bindgen can't know, this enum is not safe to format the output.
     * the value may be combined with multiple bits in many C/C++ cases,
     * for example:
     *
     * <div rustbindgen nodebug></div>
     */
    enum AVRounding {
        AV_ROUND_ZERO     = 0,
        AV_ROUND_INF      = 1,
        AV_ROUND_DOWN     = 2,
        AV_ROUND_UP       = 3,
        AV_ROUND_NEAR_INF = 5,
        AV_ROUND_PASS_MINMAX = 8192,
    };

    // Prototype
    int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding) av_const;

    // Call
    int64_t pts = av_rescale_rnd(40000, 3600, 90000, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);

# Preventing the Derivation of `Default`

`bindgen` will attempt to derive/impl the `Default` traits on a best-effort basis. Sometimes, we need customize the implement of `Default` for certain types, In these cases, the `nodefault` annotation can be used to prevent bindgen to autoderive the `Default` traits for a type.

### Library

- `bindgen::Builder::no_default`

### Command Line

- `--no-default <regex>`

### Annotations

    /**
     * We need to specify some preset values as the Default of Header.
     *
     * for example:
     *
     * <div rustbindgen nodefault></div>
     */
    struct Header {
        unsigned int magic;
        unsigned char data[252];
    };

    ...

### Customize Implements

    // Include the generated bindings.
    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

    impl Default for Header {
        fn default() -> Self {
            Self {
                magic: 0x10203040u32,
                data: [0; 252usize],
            }
        }
    }

# Annotating types with `#[must-use]`

`bindgen` can be instructed to annotate certain types with `#[must_use]`.

Some libraries have a common error type, returned by lots of their functions, which needs to be checked after every call. In these cases it’s useful to add `#[must_use]` to this type, so the Rust compiler emits a warning when the check is missing.

### Library

- `bindgen::Builder::must_use_type`

### Command Line

- `--must-use-type <regex>`

### Annotations

    /** <div rustbindgen mustusetype></div> */
    struct ErrorType {
        // ...
    };

    ...

# Making fields private

Fields can be made private for various reasons. You may wish to enforce some invariant on the fields of a structure, which cannot be achieved if the field is public and can be set by any code. For example, you may wish to ensure that a pointer always points to something appropriate.

### Annotation

    struct OneFieldPrivate {
        /** Null-terminated, static string. <div rustbindgen private> */
        const char *s;
        bool b;
    };

    /** <div rustbindgen private> */
    struct MostFieldsPrivate {
        int a;
        bool b;
        /** <div rustbindgen private="false"></div> */
        char c;
    };

Then in Rust:

    #![allow(unused)]
    fn main() {
    #[repr(C)]
    pub struct OneFieldPrivate {
        s: *const ::std::os::raw::c_char,
        pub b: bool,
    }

    impl OneFieldPrivate {
        pub fn new(s: &'static std::ffi::CStr, b: bool) -> Self {
            OneFieldPrivate { s: s.as_ptr(), b }
        }
    }
    }

# Code Formatting

`bindgen` uses `rustfmt` to format the emitted bindings. This section describes how to adjust the `rustfmt` behavior when being used from `bindgen`.

## Passing a `rustfmt.toml` configuration file

`rustfmt` should automatically use any `rustfmt.toml` file that is present in the directory from where `bindgen` will be run. If you want to use a configuration file that has a different name or that is in a different directory you can use the `--rustfmt-configuration-file` flag or the `Builder::rustfmt_configuration_file` method.

## Using a nightly release of `rustfmt`

If the `rustfmt` command does not correspond to a nightly release of `rustfmt` but you have `rustup` available, you can use `nightly` by following these steps:

### When using `bindgen` as a CLI application

Use `rustup run` to run `bindgen`:

    $ rustup run nightly bindgen [ARGS]

### When using `bindgen` as a library

Take the output of the following command:

    $ rustup which rustfmt --toolchain=nightly

and pass it to `Builder::with_rustfmt`:

    use bindgen::Builder;
    use std::process::Command;

    fn main() {
        let output = Command::new("rustup")
            .args(["which", "rustfmt", "--toolchain", "nightly"])
            .output()
            .expect("Could not spawn `rustup` command");

        assert!(
            output.status.success(),
            "Unsuccessful status code when running `rustup`: {output:?}",
        );

        let rustfmt_path =
            String::from_utf8(output.stdout).expect("The `rustfmt` path is not valid `utf-8`");

        let bindings = Builder::default()
            .header("path/to/input.h")
            .with_rustfmt(rustfmt_path)
            .generate()
            .expect("Could not generate bindings");

        bindings
            .write_to_file("path/to/output.rs")
            .expect("Could not write bindings");
    }

These two methods also apply to any other toolchain available in your system.

## Using `prettyplease`

The `prettyplease` crate is a minimal formatter for generated code. To format bindings using `prettyplease` you have to invoke `bindgen` with either the `--formatter=prettyplease` flag or the `bindgen::Builder::formatter(bindgen::Formatter::Prettyplease)`. One of its advantages is that `prettyplease` can be used in minimal environments where the Rust toolchain is not installed.

## How can I normalize `#[doc]` attributes?

`bindgen` emits all the documentation using `#[doc]` attributes by default. If you want to use the more user-friendly `///` syntax, you have two options:

### Use `rustfmt`

`rustfmt` can be configured to normalize documentation. To do so, you have to create a `rustfmt.toml` file with the following contents:

    normalize_doc_attributes = true

Then, you have set up `bindgen` so it passes this file to `rustfmt`. Given that the `normalize_doc_attributes` option is unstable, you also have to set up bindgen to use a `nightly` release of `rustfmt`.

### Use `prettyplease`

`prettyplease` normalizes documentation without any additional configuration. Then you just have to tell `bindgen` to use `prettyplease` as the code formatter.

# Generating Bindings to C++

`bindgen` can handle some C++ features, but not all of them. To set expectations: `bindgen` will give you the type definitions and FFI declarations you need to build an API to the C++ library, but using those types in Rust will be nowhere near as nice as using them in C++. You will have to manually call constructors, destructors, overloaded operators, etc yourself.

When passing in header files, the file will automatically be treated as C++ if it ends in `.hpp`. If it doesn’t, adding `clang_args(["-x", "c++"])` can be used to force C++ mode. You probably also want to use `-std=c++14` or similar clang args as well.

You pretty much must use allowlisting when working with C++ to avoid pulling in all of the `std::.*` types, many of which `bindgen` cannot handle. Additionally, you may want to mark other types as opaque that `bindgen` stumbles on. It is recommended to mark all of `std::.*` opaque, and to allowlist only precisely the functions and types you intend to use.

You should read up on the FAQs as well.

## Supported Features

- Inheritance (for the most part; there are some outstanding bugs)

- Methods

- Bindings to constructors and destructors (but they aren’t implicitly or automatically invoked)

- Function and method overloading

- Templates without specialization. You should be able to access individual fields of the class or struct.

## Unsupported Features

When `bindgen` finds a type that is too difficult or impossible to translate into Rust, it will automatically treat it as an opaque blob of bytes. The philosophy is that

1. we should always get layout, size, and alignment correct, and

2. just because one type uses specialization, that shouldn’t cause `bindgen` to give up on everything else.

Without further ado, here are C++ features that `bindgen` does not support or cannot translate into Rust:

- Inline functions and methods: see “Why isn’t `bindgen` generating bindings to inline functions?”

- Template functions, methods of template classes and structs. We don’t know which monomorphizations exist, and can’t create new ones because we aren’t a C++ compiler.

- Anything related to template specialization:

  - Partial template specialization
  - Traits templates
  - Substitution Failure Is Not An Error (SFINAE)

- Cross language inheritance, for example inheriting from a Rust struct in C++.

- Automatically calling copy and/or move constructors or destructors. Supporting this isn’t possible with Rust’s move semantics.

- Exceptions: if a function called through a `bindgen`-generated interface raises an exception that is not caught by the function itself, this will generate undefined behaviour. See the tracking issue for exceptions for more details.

- Many C++ specific aspects of calling conventions. For example in the Itanium abi types that are “non trivial for the purposes of calls” should be passed by pointer, even if they are otherwise eligible to be passed in a register. Similarly in both the Itanium and MSVC ABIs such types are returned by “hidden parameter”, much like large structs in C that would not fit into a register. This also applies to types with any base classes in the MSVC ABI (see x64 calling convention). Because bindgen does not know about these rules generated interfaces using such types are currently invalid.

## Constructor semantics

`bindgen` will generate a wrapper for any class constructor declared in the input headers. For example, this headers file

    class MyClass {
        public:
    	MyClass();
            void method();
    };

Will produce the following code:

    #[repr(C)]
    #[derive(Debug, Copy, Clone)]
    pub struct MyClass {
        pub _address: u8,
    }
    extern "C" {
        #[link_name = "\u{1}_ZN7MyClass6methodEv"]
        pub fn MyClass_method(this: *mut MyClass);
    }
    extern "C" {
        #[link_name = "\u{1}_ZN7MyClassC1Ev"]
        pub fn MyClass_MyClass(this: *mut MyClass);
    }
    impl MyClass {
        #[inline]
        pub unsafe fn method(&mut self) {
            MyClass_method(self)
        }
        #[inline]
        pub unsafe fn new() -> Self {
            let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit();
            MyClass_MyClass(__bindgen_tmp.as_mut_ptr());
            __bindgen_tmp.assume_init()
        }
    }

This `MyClass::new` Rust method can be used as a substitute for the `MyClass` C++ constructor. However, the address of the value from inside the method will be different than from the outside. This is because the `__bindgen_tmp` value is moved when the `MyClass::new` method returns.

In contrast, the C++ constructor will not move the value, meaning that the address of the value will be the same inside and outside the constructor. If the original C++ relies on this semantic difference somehow, you should use the `MyClass_MyClass` binding directly instead of the `MyClass::new` method.

In other words, the Rust equivalent for the following C++ code

    MyClass instance = MyClass();
    instance.method();

is not this

    let instance = MyClass::new();
    instance.method();

but this

    let instance = std::mem::MaybeUninit::<MyClass>::uninit();
    MyClass_MyClass(instance.as_mut_ptr());
    instance.assume_init_mut().method();

You can easily verify this fact if you provide a implementation for `MyClass` and `method` that prints the `this` pointer address. However, you can ignore this fact if you know that the original C++ code does not rely on the instance address in its internal logic.

# Generating Bindings to Objective-C

`bindgen` does not (yet) have full objective-c support but it can generate bindings for a lot of the apple frameworks without too much blocklisting.

In order to generate bindings, you will need `-x objective-c` as the clang args. If you’d like to use block you will need `-fblocks` as a clang arg as well.

Depending on your setup, you may need `--generate-block` to generate the block function aliases and `--block-extern-crate` to insert a `extern crate block` at the beginning of the generated bindings. The same logic applies to the `--objc-extern-crate` parameter.

The objective-c classes will be represented as a `struct Foo(id)` and a trait `IFoo` where `Foo` is the objective-c class and `id` is an alias for `*mut objc::runtime::Object` (the pointer to the objective-c instance). The trait `IFoo` is needed to allow for the generated inheritance.

Functions that use or return objective-c pointers of instance `Foo` will return `Foo`. The reason this works is because `Foo` represented as `transparent`. This will be helpful for a lot of objective-c frameworks however there are some cases where functions return `instancetype` which is a type alias for `id` so an occasional `foo.0` may be required. An example of this would in the UIKit framework should you want to add a `UILabel` to a UIStackView you will need to convert the `UILabel` to a `UIView` via `UIView(label.0)`.

Each class (struct) has an `alloc` and a `dealloc` to match that of some of the alloc methods found in `NSObject`.

In order to initialize a class `Foo`, you will have to do something like `let foo = Foo(Foo::alloc().initWithStuff())`.

To blocklist an Objective-C method, you should add the bindgen generated method path (e.g. `IFoo::method` or `IFoo::class_method`) as a blocklist item.

## Supported Features

- Inheritance matched to rust traits with prefixes of `I` which stands for interface.
- Protocols which match to rust traits with prefixes of `P` which stands for Protocol.
- Classes will generate `struct Foo(id)` where `Foo` is the class name and `id` is a pointer to the objective-c Object.
- Blocks

## Useful Notes

- If you’re targeting `aarch64-apple-ios`, you’ll need to have the clang arg `--target=arm64-apple-ios` as mentioned here.
- The generated bindings will almost certainly have some conflicts so you will have to blocklist a few things. There are a few cases of the parameters being poorly named in the objective-c headers. But if you’re using anything with Core Foundation, you’ll find that `time.h` as has a variable called timezone that conflicts with some of the things in `NSCalendar.h`.
- Some small subset of the function headers in the apple frameworks go against apple’s guidelines for parameter names and duplicate the names in the header which won’t compile as mentioned here.
- instancetype return methods does not return `Self` for you given class, it returns a `mut * objc::runtime::Objc` which is aliased as `id`. This is because objective-c’s inheritance doesn’t perfectly match that of rusts.
- Depending on what you’re trying `bindgen` against, you may end up including all of Core Foundation and any other frameworks. This will result in a very long compile time.

## Not (yet) Supported

- Nullability attributes which return `Option`s.
- Probably many other things. Feel free to open an issue.

# Example crate(s)

- uikit-sys

# Using the Union Types Generated by Bindgen

NOTE: Rust 1.19 stabilized the `union` type (see Rust issue #32836).

You can pass the `--rust-target` option to tell `bindgen` to target a specific version of Rust. By default, `bindgen` will target the latest stable Rust. The `--rust-target` option accepts a specific stable version (such as “1.0” or “1.19”) or “nightly”.

NOTE: The `--unstable-rust` option is deprecated; use `--rust-target nightly` instead.

In general, most interactions with unions (either reading or writing) are unsafe, meaning you must surround union accesses in an `unsafe {}` block.

For this discussion, we will use the following C type definitions:

    typedef struct {
        int32_t a;
        int32_t b;
    } alpha_t;

    typedef struct {
        uint32_t c;
        uint16_t d;
        uint16_t e;
        uint8_t  f;
    } beta_t;

    typedef union {
        alpha_t alfa;
        beta_t  bravo;
    } greek_t;

## Relevant Bindgen Options

### Library

- `bindgen::Builder::rust_target()`
- `bindgen::Builder::derive_default()`

### Command Line

- `--rust-target`
- `--with-derive-default`

## Which union type will Bindgen generate?

Bindgen can emit one of two Rust types that correspond to C unions:

- Rust’s `union` builtin (only available in Rust >= 1.19, including nightly)
- Bindgen’s `BindgenUnion` (available for all Rust targets)

Bindgen uses the following logic to determine which Rust union type to emit:

- If the Rust target is >= 1.19 (including nightly) AND each field of the union can derive `Copy`, then generate a `union` builtin.
- Otherwise, generate a `BindgenUnion`.

## Using the `union` builtin

When using the `union` builtin type, there are two choices for initialization:

1. Zero
2. With a specific variant

    mod bindings_builtin_union;

    fn union_builtin() {
        // Initialize the union to zero
        let x = bindings_builtin_union::greek_t::default();

        // If `--with-derive-default` option is not used, the following may be used
        //   to initialize the union to zero:
        let x = unsafe { std::mem::zeroed::<bindings_builtin_union::greek_t>() };

        // Or, it is possible to initialize exactly one variant of the enum:
        let x = bindings_builtin_union::greek_t {
            alfa: bindings_builtin_union::alpha_t {
                a: 1,
                b: -1,
            },
        };

        unsafe {
            println!("{:?}", z.alfa);  // alpha_t { a: 1, b: -1 }
            println!("{:?}", z.bravo); // beta_t { c: 1, d: 65535, e: 65535, f: 127 }
        }
    }

## Using the `BindgenUnion` type

If the target Rust version does not support the new `union` type or there is a field that cannot derive `Copy`, then bindgen will provide union-like access to a `struct`.

Interacting with these unions is slightly different than the new `union` types. You must access union variants through a reference.

    mod bindings;

    fn bindgenunion() {
        // `default()` or `zeroed()` may still be used with Bindgen's Union types
        let mut x = bindings::greek_t::default();

        // This will not work:
        // let x = bindings::greek_t {
        //     alfa: bindings::alpha_t {
        //         a: 1,
        //         b: -1,
        //     },
        // };

        // Instead, access the field through `.as_ref()` and `.as_mut()` helpers:
        unsafe {
            *x.alfa.as_mut() = bindings::alpha_t {
                a: 1,
                b: -1,
            };

            println!("{:?}", x.alfa.as_ref());  // alpha_t { a: 1, b: -1 }
            println!("{:?}", x.bravo.as_ref()); // beta_t { c: 1, d: 65535, e: 65535, f: 0 }
        }

If you attempt to access a `BindgenUnion` field directly, you will see errors like this:

    error[E0308]: mismatched types
      --> src/main.rs:44:15
       |
    44 |           alfa: bindings::alpha_t {
       |  _______________^
    45 | |             a: 1,
    46 | |             b: -1,
    47 | |         },
       | |_________^ expected struct `bindings::__BindgenUnionField`, found struct `bindings::alpha_t`
       |
       = note: expected type `bindings::__BindgenUnionField<bindings::alpha_t>`
                  found type `bindings::alpha_t`

# Using the Bitfield Types Generated by Bindgen

## Bitfield Strategy Overview

As Rust does not support bitfields, Bindgen generates a struct for each with the following characteristics

- Immutable getter functions for each bitfield named `<bitfield>`
- Setter functions for each contiguous block of bitfields named `set_<bitfield>`
- For each contiguous block of bitfields, Bindgen emits an opaque physical field that contains one or more logical bitfields
- A static constructor `new_bitfield_{1, 2, ...}` with a parameter for each bitfield contained within the opaque physical field.

To keep bindgen from generating the bitfield unit struct, it can be blocklisted like any other type, i.e. `--blocklist-type "__BindgenBitfieldUnit"`. This may be useful if you want to define a custom implementation, or your generated bindings import a pre-existing definition for the bitfield unit type.

## Bitfield examples

For this discussion, we will use the following C type definitions and functions.

    typedef struct {
        unsigned int a: 1;
        unsigned int b: 1;
        unsigned int c: 2;

    } StructWithBitfields;

    // Create a default bitfield
    StructWithBitfields create_bitfield();

    // Print a bitfield
    void print_bitfield(StructWithBitfields bfield);

Bindgen creates a set of field getters and setters for interacting with the bitset. For example,

        let mut bfield = unsafe { create_bitfield() };

        bfield.set_a(1);
        println!("a set to {}", bfield.a());
        bfield.set_b(1);
        println!("b set to {}", bfield.b());
        bfield.set_c(3);
        println!("c set to {}", bfield.c());

        unsafe { print_bitfield(bfield) };

will print out

    a set to 1
    b set to 1
    c set to 3
    StructWithBitfields: a:1, b:1, c:3

Overflowing a bitfield will result in the same behavior as in C/C++: the bitfield will be set to 0.

        let mut bfield = unsafe { create_bitfield() };
        bfield.set_a(1);
        bfield.set_b(1);
        bfield.set_c(12);
        println!("c set to {} due to overflow", bfield.c());

        unsafe { print_bitfield(bfield) };

will print out

    c set to 0 due to overflow
    StructWithBitfields: a:1, b:1, c:0

To create a new bitfield in Rust, use the bitfield allocation unit constructor.

Note: This requires the Builder’s derive_default to be set to true, otherwise the necessary Default functions won’t be generated.

        let bfield = StructWithBitfields{
            _bitfield_1: StructWithBitfields::new_bitfield_1(0,0,0),
            ..Default::default()
        };

        unsafe { print_bitfield(bfield) };

This will print out

    StructWithBitfields: a:0, b:0, c:0

# Using C structures with Flexible Array Members

Since time immemorial, C programmers have been using what was called “the struct hack”. This is a technique for packing a fixed-size structure and a variable-sized tail within the same memory allocation. Typically this looks like:

    struct MyRecord {
        time_t timestamp;
        unsigned seq;
        size_t len;
        char payload[0];
    };

Because this is so useful, it was standardized in C99 as “flexible array members”, using almost identical syntax:

    struct MyRecord {
        time_t timestamp;
        unsigned seq;
        size_t len;
        char payload[]; // NOTE: empty []
    };

Bindgen supports these structures in two different ways.

## `__IncompleteArrayField`

By default, bindgen will generate the corresponding Rust structure:

    #[repr(C)]
    struct MyRecord {
        pub timestamp: time_t,
        pub seq: ::std::os::raw::c_uint,
        pub len: usize,
        pub payload: __IncompleteArrayField<::std::os::raw::c_char>,
    }

The `__IncompleteArrayField` type is zero-sized, so this structure represents the prefix without any trailing data. In order to access that data, it provides the `as_slice` unsafe method:

        // SAFETY: there's at least `len` bytes allocated and initialized after `myrecord`
        let payload = unsafe { myrecord.payload.as_slice(myrecord.len) };

There’s also `as_mut_slice` which does the obvious.

These are `unsafe` simply because it’s up to you to provide the right length (in elements of whatever type `payload` is) as there’s no way for Rust or Bindgen to know. In this example, the length is a very straightforward `len` field in the structure, but it could be encoded in any number of ways within the structure, or come from somewhere else entirely.

One big caveat with this technique is that `std::mem::size_of` (or `size_of_val`) will only include the size of the prefix structure. if you’re working out how much storage the whole structure is using, you’ll need to add the suffix yourself.

## Using Dynamically Sized Types

If you invoke bindgen with the `--flexarray-dst` option, it will generate something not quite like this:

    #[repr(C)]
    struct MyRecord {
        pub timestamp: time_t,
        pub seq: ::std::os::raw::c_uint,
        pub len: usize,
        pub payload: [::std::os::raw::c_char],
    }

Rust has a set of types which are almost exact analogs for these Flexible Array Member types: the Dynamically Sized Type (“DST”).

This looks almost identical to a normal Rust structure, except that you’ll note the type of the `payload` field is a raw slice `[...]` rather than the usual reference to slice `&[...]`.

That `payload: [c_char]` is telling Rust that it can’t directly know the total size of this structure - the `payload` field takes an amount of space that’s determined at runtime. This means you can’t directly use values of this type, only references: `&MyRecord`.

In practice, this is very awkward. So instead, bindgen generates:

    #[repr(C)]
    struct MyRecord<FAM: ?Sized = [::std::os::raw::c_char; 0]> {
        pub timestamp: time_t,
        pub seq: ::std::os::raw::c_uint,
        pub len: usize,
        pub payload: FAM,
    }

That is:

1. a type parameter `FAM` which represents the type of the `payload` field,
2. it’s `?Sized` meaning it can be unsized (ie, a DST)
3. it has the default type of `[c_char; 0]` - that is a zero-sized array of characters

This means that referencing plain `MyRecord` will be exactly like `MyRecord` with `__IncompleteArrayField`: it is a fixed-sized structure which you can manipulate like a normal Rust value.

But how do you get to the DST part?

Bindgen will also implement a set of helper methods for this:

    // Static sized variant
    impl MyRecord<[::std::os::raw::c_char; 0]> {
        pub unsafe fn flex_ref(&self, len: usize) -> &MyRecord<[::std::os::raw::c_char]> { ... }
        pub unsafe fn flex_mut_ref(&mut self, len: usize) -> &mut MyRecord<[::std::os::raw::c_char]> { ... }
        // And some raw pointer variants
    }

These will take a sized `MyRecord<[c_char; 0]>` and a length in elements, and return a reference to a DST `MyRecord<[c_char]>` where the `payload` field is a fully usable slice of `len` characters.

The magic here is that the reference is a fat pointer, which not only encodes the address, but also the dynamic size of the final field, just like a reference to a slice is. This means that you get full bounds checked access to the `payload` field like any other Rust slice.

It also means that doing `mem::size_of_val(myrecord)` will return the complete size of this structure, including the suffix.

You can go the other way:

    // Dynamic sized variant
    impl MyRecord<[::std::os::raw::c_char]> {
        pub fn fixed(&self) -> (&MyRecord<[::std::os::raw::c_char; 0]>, usize) { ... }
        pub fn fixed_mut(&mut self) -> (&mut MyRecord<[::std::os::raw::c_char; 0]>, usize) { ... }
        pub fn layout(len: usize) -> std::alloc::Layout { ... }
    }

which takes the DST variant of the structure and returns the sized variant, along with the number of elements are after it. These are all completely safe because all the information needed is part of the fat `&self` reference.

The `layout` function takes a length and returns the `Layout` - that is, size and alignment, so that you can allocate memory for the structure (for example, using `malloc` so you can pass it to a C function).

Unfortunately the language features needed to support these methods are still unstable:

- ptr_metadata, which enables all the fixed<->DST conversions, and
- layout_for_ptr, which allows he `layout` method

As a result, if you don’t specify `--rust-target nightly` you’ll just get the bare type definitions, but no real way to use them. It’s often convenient to add the

    --raw-line '#![feature(ptr_metadata,layout_for_ptr)]'

option if you’re generating Rust as a stand-alone crate. Otherwise you’ll need to add the feature line to your containing crate.

# Frequently Asked Questions

- Why isn’t `bindgen` generating methods for this allowlisted class?
- Why isn’t `bindgen` generating bindings to inline functions?
- Does `bindgen` support the C++ Standard Template Library (STL)?
- How to deal with bindgen generated padding fields?
- How to generate bindings for a custom target?
- Why isn’t `bindgen` generating documentation for system headers?

### Why isn’t `bindgen` generating methods for this allowlisted class?

Are the methods `inline` methods, or defined inline in the class? For example:

    class Dooder {
      public:
        // Function defined inline in the class.
        int example_one() { return 1; }

        // `inline` function whose definition is supplied later in the header, or in
        // another header.
        inline bool example_two();
    };

    inline bool Dooder::example_two() {
        return true;
    }

If so, see “Why isn’t `bindgen` generating bindings to inline functions?”

If not, consider filing an issue!

### Why isn’t `bindgen` generating bindings to inline functions?

These functions don’t typically end up in object files or shared libraries with symbols that we can reliably link to, since they are instead inlined into each of their call sites. Therefore, we don’t generate bindings to them, since that creates linking errors.

However, if you are compiling the C/C++ yourself (rather than using a system shared library, for example), then you can pass `-fkeep-inline-functions` or `-fno-inline-functions` to `gcc` or `clang`, and invoke `bindgen` with either the `bindgen::Builder::generate_inline_functions` method or the `--generate-inline-functions` flag.

Note that these functions and methods are usually marked inline for a reason: they tend to be hot. The above workaround makes them an out-of-line call, which might not provide acceptable performance.

As an alternative, you can invoke `bindgen` with either the `bindgen::Builder::wrap_static_fns` method or the `--wrap-static-fns` flag. Which generates a C source file that can be compiled against the input headers to produce Rust headers for `static` and `static inline` functions. See How to handle `static inline` functions for further information.

### Does `bindgen` support the C++ Standard Template Library (STL)?

Sort of. A little. Depends what you mean by “support”.

Most functions, methods, constructors, and destructors are inline in the STL. That ties our hands when it comes to linking: “Why isn’t `bindgen` generating bindings to inline functions?”

As far as generating opaque blobs of bytes with the correct size and alignment, `bindgen` can do pretty well. This is typically enough to let you use types that transitively contain STL things. We generally recommend marking `std::.*` as opaque, and then allowlisting only the specific things you need from the library you’re binding to that is pulling in STL headers.

### How to deal with bindgen generated padding fields?

Depending the architecture, toolchain versions and source struct, it is possible that bindgen will generate padding fields named `__bindgen_padding_N`. As these fields might be present when compiling for one architecture but not for an other, you should not initialize these fields manually when initializing the struct. Instead, use the `Default` trait. You can either enable this when constructing the `Builder` using the `derive_default` method, or you can implement this per struct using:

    impl Default for SRC_DATA {
        fn default() -> Self {
            unsafe { std::mem::zeroed() }
        }
    }

This makes it possible to initialize `SRC_DATA` by:

    SRC_DATA {
        field_a: "foo",
        field_b: "bar",
        ..Default::default()
    }

In the case bindgen generates a padding field, then this field will be automatically initialized by `..Default::default()`.

### How to generate bindings for a custom target?

To generate bindings for a custom target you only need to pass the `--target` argument to `libclang`. For example, if you want to generate bindings for the `armv7a-none-eabi` target using the command line, you need to invoke `bindgen` like so:

    $ bindgen <input_headers> -- --target=armv7a-none-eabi

If you are using `bindgen` as a library, you should call `builder.clang_arg("--target=armv7a-none-eabi")` on your `builder`.

### Why isn’t `bindgen` generating documentation for system headers?

By default, Bindgen does not generate documentation for system headers because `libclang` does not provide this information. To address this, you should call `builder.clang_arg("-fretain-comments-from-system-headers")` on your `builder`.