blob: d6b1306adb94a2fa019f2b30255413d9ab542bf0 [file] [log] [blame]
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>The bindgen User Guide</title>
<meta name="robots" content="noindex" />
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="`bindgen` automatically generates Rust FFI bindings to C and C++ libraries.">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="requirements.html"><strong aria-hidden="true">2.</strong> Requirements</a></li><li class="chapter-item expanded "><a href="library-usage.html"><strong aria-hidden="true">3.</strong> Library Usage with build.rs</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tutorial-0.html"><strong aria-hidden="true">3.1.</strong> Tutorial</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tutorial-1.html"><strong aria-hidden="true">3.1.1.</strong> Add bindgen as a Build Dependency</a></li><li class="chapter-item expanded "><a href="tutorial-2.html"><strong aria-hidden="true">3.1.2.</strong> Create a wrapper.h Header</a></li><li class="chapter-item expanded "><a href="tutorial-3.html"><strong aria-hidden="true">3.1.3.</strong> Create a build.rs File</a></li><li class="chapter-item expanded "><a href="tutorial-4.html"><strong aria-hidden="true">3.1.4.</strong> Include the Generated Bindings in src/lib.rs</a></li><li class="chapter-item expanded "><a href="tutorial-5.html"><strong aria-hidden="true">3.1.5.</strong> Write a Sanity Test</a></li><li class="chapter-item expanded "><a href="tutorial-6.html"><strong aria-hidden="true">3.1.6.</strong> Publish Your Crate!</a></li></ol></li><li class="chapter-item expanded "><a href="non-system-libraries.html"><strong aria-hidden="true">3.2.</strong> Bindings for non-system libraries</a></li></ol></li><li class="chapter-item expanded "><a href="command-line-usage.html"><strong aria-hidden="true">4.</strong> Command Line Usage</a></li><li class="chapter-item expanded "><a href="customizing-generated-bindings.html"><strong aria-hidden="true">5.</strong> Customizing the Generated Bindings</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="allowlisting.html"><strong aria-hidden="true">5.1.</strong> Allowlisting</a></li><li class="chapter-item expanded "><a href="blocklisting.html"><strong aria-hidden="true">5.2.</strong> Blocklisting</a></li><li class="chapter-item expanded "><a href="opaque.html"><strong aria-hidden="true">5.3.</strong> Treating a Type as an Opaque Blob of Bytes</a></li><li class="chapter-item expanded "><a href="replacing-types.html"><strong aria-hidden="true">5.4.</strong> Replacing One Type with Another</a></li><li class="chapter-item expanded "><a href="nocopy.html"><strong aria-hidden="true">5.5.</strong> Preventing the Derivation of Copy and Clone</a></li><li class="chapter-item expanded "><a href="nodebug.html"><strong aria-hidden="true">5.6.</strong> Preventing the Derivation of Debug</a></li><li class="chapter-item expanded "><a href="nodefault.html"><strong aria-hidden="true">5.7.</strong> Preventing the Derivation of Default</a></li><li class="chapter-item expanded "><a href="must-use-types.html"><strong aria-hidden="true">5.8.</strong> Annotating types with #[must-use]</a></li><li class="chapter-item expanded "><a href="visibility.html"><strong aria-hidden="true">5.9.</strong> Field visibility</a></li><li class="chapter-item expanded "><a href="code-formatting.html"><strong aria-hidden="true">5.10.</strong> Code formatting</a></li></ol></li><li class="chapter-item expanded "><a href="cpp.html"><strong aria-hidden="true">6.</strong> Generating Bindings to C++</a></li><li class="chapter-item expanded "><a href="objc.html"><strong aria-hidden="true">7.</strong> Generating Bindings to Objective-c</a></li><li class="chapter-item expanded "><a href="using-unions.html"><strong aria-hidden="true">8.</strong> Using Unions</a></li><li class="chapter-item expanded "><a href="using-bitfields.html"><strong aria-hidden="true">9.</strong> Using Bitfields</a></li><li class="chapter-item expanded "><a href="using-fam.html"><strong aria-hidden="true">10.</strong> Using Flexible Array Members</a></li><li class="chapter-item expanded "><a href="faq.html"><strong aria-hidden="true">11.</strong> FAQ</a></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">The bindgen User Guide</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/rust-lang/rust-bindgen" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" name="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1><a class="header" href="#introduction" id="introduction">Introduction</a></h1>
<p><strong><a href="https://github.com/rust-lang/rust-bindgen"><code>bindgen</code></a> automatically generates Rust
FFI bindings to C and C++ libraries.</strong></p>
<p>For example, given the C header <code>cool.h</code>:</p>
<pre><code class="language-c">typedef struct CoolStruct {
int x;
int y;
} CoolStruct;
void cool_function(int i, char c, CoolStruct* cs);
</code></pre>
<p><code>bindgen</code> produces Rust FFI code allowing you to call into the <code>cool</code> library's
functions and use its types:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>/* 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 &quot;C&quot; {
pub fn cool_function(i: ::std::os::raw::c_int,
c: ::std::os::raw::c_char,
cs: *mut CoolStruct);
}
<span class="boring">}
</span></code></pre></pre>
<h1><a class="header" href="#requirements" id="requirements">Requirements</a></h1>
<p>This page lists the requirements for running <code>bindgen</code> and how to get them.</p>
<h2><a class="header" href="#clang" id="clang">Clang</a></h2>
<p><code>bindgen</code> leverages <code>libclang</code> to preprocess, parse, and type check C and C++
header files.</p>
<p>It is required to use Clang 5.0 or greater.</p>
<h3><a class="header" href="#installing-clang" id="installing-clang">Installing Clang</a></h3>
<h4><a class="header" href="#windows" id="windows">Windows</a></h4>
<p>If you use winget:</p>
<pre><code class="language-powershell">winget install LLVM.LLVM
</code></pre>
<p>Alternatively, you can download and install the official pre-built binary from
<a href="http://releases.llvm.org/download.html">LLVM download page</a>.</p>
<p>You will also need to set <code>LIBCLANG_PATH</code> as an <a href="https://www.techjunkie.com/environment-variables-windows-10/">environment
variable</a> pointing
to the <code>bin</code> directory of your LLVM install. For example, if you installed LLVM
to <code>D:\programs\LLVM</code>, then you'd set the value to be <code>D:\programs\LLVM\bin</code>.</p>
<p>Alternatively, for Mingw64, you can install clang via</p>
<pre><code class="language-bash">pacman -S mingw64/mingw-w64-x86_64-clang
</code></pre>
<h4><a class="header" href="#macos" id="macos">macOS</a></h4>
<p>If you use Homebrew:</p>
<pre><code class="language-bash">$ brew install llvm
</code></pre>
<p>If you use MacPorts:</p>
<pre><code class="language-bash">$ port install clang
</code></pre>
<h4><a class="header" href="#debian-based-linuxes" id="debian-based-linuxes">Debian-based Linuxes</a></h4>
<pre><code class="language-bash"># apt install llvm-dev libclang-dev clang
</code></pre>
<p>Ubuntu 18.04 provides the necessary packages directly.</p>
<h4><a class="header" href="#arch" id="arch">Arch</a></h4>
<pre><code class="language-bash"># pacman -S clang
</code></pre>
<h4><a class="header" href="#fedora" id="fedora">Fedora</a></h4>
<pre><code class="language-bash"># dnf install clang-devel
</code></pre>
<h4><a class="header" href="#openbsd" id="openbsd">OpenBSD</a></h4>
<pre><code class="language-bash"># pkg_add llvm
</code></pre>
<p>Add <code>export LIBCLANG_PATH=/usr/local/lib</code> to your profile.</p>
<h4><a class="header" href="#from-source" id="from-source">From source</a></h4>
<p>If your package manager doesn't yet offer Clang 5.0, you'll need to build from
source. For that, follow the
instructions <a href="http://clang.llvm.org/get_started.html">here</a>.</p>
<p>Those instructions list optional steps. For <code>bindgen</code>:</p>
<ul>
<li>Checkout and build clang</li>
<li>Checkout and build the extra-clang-tools</li>
<li>You do not need to checkout or build compiler-rt</li>
<li>You do not need to checkout or build libcxx</li>
</ul>
<h1><a class="header" href="#library-usage-with-buildrs" id="library-usage-with-buildrs">Library Usage with <code>build.rs</code></a></h1>
<p>💡 This is the recommended way to use <code>bindgen</code>. 💡</p>
<p>Often times C and C++ headers will have platform- and architecture-specific
<code>#ifdef</code>s that affect the shape of the Rust FFI bindings we need to create to
interface Rust code with the outside world. By using <code>bindgen</code> as a library
inside your <code>build.rs</code>, you can generate bindings for the current target
on-the-fly. Otherwise, you would need to generate and maintain
<code>x86_64-unknown-linux-gnu-bindings.rs</code>, <code>x86_64-apple-darwin-bindings.rs</code>,
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
<code>libclang</code> available to run <code>bindgen</code>.</p>
<h2><a class="header" href="#library-api-documentation" id="library-api-documentation">Library API Documentation</a></h2>
<p><a href="https://docs.rs/bindgen">📚 There is complete API reference documentation on docs.rs 📚</a></p>
<h2><a class="header" href="#tutorial" id="tutorial">Tutorial</a></h2>
<p>The next section contains a detailed, step-by-step tutorial for using <code>bindgen</code>
as a library inside <code>build.rs</code>.</p>
<h1><a class="header" href="#tutorial-1" id="tutorial-1">Tutorial</a></h1>
<p>The following tutorial is adapted from <a href="http://fitzgeraldnick.com/2016/12/14/using-libbindgen-in-build-rs.html">this blog post</a>.</p>
<p>What follows is a whirlwind introductory tutorial to using <code>bindgen</code> from inside
<code>build.rs</code>. We'll generate bindings to <code>bzip2</code> (which is available on most
systems) on-the-fly.</p>
<p><a href="https://github.com/fitzgen/bindgen-tutorial-bzip2-sys"><strong>TL;DR?</strong> The full tutorial code is available here.</a></p>
<h1><a class="header" href="#add-bindgen-as-a-build-dependency" id="add-bindgen-as-a-build-dependency">Add <code>bindgen</code> as a Build Dependency</a></h1>
<p>First we need to declare a build-time dependency on <code>bindgen</code> by adding it to
the <code>[build-dependencies]</code> section of our crate's <code>Cargo.toml</code> file.</p>
<p>Please always use the latest version of <code>bindgen</code>, as it has the most fixes and
best compatibility.
You can always check the latest version at
<a href="https://crates.io/crates/bindgen">the bindgen page in crates.io</a>.</p>
<pre><code class="language-toml">[build-dependencies]
bindgen = &quot;0.65.1&quot;
</code></pre>
<blockquote>
<p>⚠️ <strong>Warning</strong></p>
<p><code>bindgen</code> needs to be added to the <code>[build-dependencies]</code> section, not the normal
<code>[dependencies]</code> section. If you add it as a regular dependency, you will get
errors like the following: <code>error[E0463]: can't find crate for `bindgen`</code></p>
</blockquote>
<h1><a class="header" href="#create-a-wrapperh-header" id="create-a-wrapperh-header">Create a <code>wrapper.h</code> Header</a></h1>
<p>The <code>wrapper.h</code> file will include all the various headers containing
declarations of structs and functions we would like bindings for. In the
particular case of <code>bzip2</code>, this is pretty easy since the entire public API is
contained in a single header. For a project like <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/How_to_embed_the_JavaScript_engine">SpiderMonkey</a>,
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 <code>wrapper.h</code> entry point for <code>bindgen</code>.</p>
<p>Here is our <code>wrapper.h</code>:</p>
<pre><code class="language-c">#include &lt;bzlib.h&gt;
</code></pre>
<p>This is also where we would add any <a href="./replacing-types.html">replacement types</a>,
if we were using some.</p>
<h1><a class="header" href="#create-a-buildrs-file" id="create-a-buildrs-file">Create a <code>build.rs</code> File</a></h1>
<p>We create a <code>build.rs</code> 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 <code>bzip2</code> at compile time. The resulting bindings will be written to
<code>$OUT_DIR/bindings.rs</code> where <code>$OUT_DIR</code> is chosen by <code>cargo</code> and is something
like <code>./target/debug/build/bindgen-tutorial-bzip2-sys-afc7747d7eafd720/out/</code>.</p>
<p>Note that the associated shared object to <code>bz2</code> is <code>libbz2.so</code>. In general, a <code>lib&lt;name&gt;.so</code> should be referenced in the build file by <code>&lt;name&gt;</code>.</p>
<pre><code class="language-rust ignore">use std::env;
use std::path::PathBuf;
fn main() {
// Tell cargo to look for shared libraries in the specified directory
println!(&quot;cargo:rustc-link-search=/path/to/lib&quot;);
// Tell cargo to tell rustc to link the system bzip2
// shared library.
println!(&quot;cargo:rustc-link-lib=bz2&quot;);
// 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(&quot;wrapper.h&quot;)
// 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(&quot;Unable to generate bindings&quot;);
// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from(env::var(&quot;OUT_DIR&quot;).unwrap());
bindings
.write_to_file(out_path.join(&quot;bindings.rs&quot;))
.expect(&quot;Couldn't write bindings!&quot;);
}
</code></pre>
<p>Now, when we run <code>cargo build</code>, our bindings to <code>bzip2</code> are generated on the
fly!</p>
<p><a href="https://doc.rust-lang.org/cargo/reference/build-scripts.html">There's more info about <code>build.rs</code> files in the Cargo documentation.</a></p>
<h1><a class="header" href="#include-the-generated-bindings-in-srclibrs" id="include-the-generated-bindings-in-srclibrs">Include the Generated Bindings in <code>src/lib.rs</code></a></h1>
<p>We can use the <code>include!</code> macro to dump our generated bindings right into our
crate's main entry point, <code>src/lib.rs</code>:</p>
<pre><code class="language-rust ignore">#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
include!(concat!(env!(&quot;OUT_DIR&quot;), &quot;/bindings.rs&quot;));
</code></pre>
<p>Because <code>bzip2</code>'s symbols do not follow Rust's style conventions, we suppress a
bunch of warnings with a few <code>#![allow(...)]</code> pragmas.</p>
<p>We can run <code>cargo build</code> again to check that the bindings themselves compile:</p>
<pre><code class="language-bash">$ cargo build
Compiling bindgen-tutorial-bzip2-sys v0.1.0
Finished debug [unoptimized + debuginfo] target(s) in 62.8 secs
</code></pre>
<p>And we can run <code>cargo test</code> to verify that the layout, size, and alignment of
our generated Rust FFI structs match what <code>bindgen</code> thinks they should be:</p>
<pre><code class="language-bash">$ 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
</code></pre>
<h1><a class="header" href="#write-a-sanity-test" id="write-a-sanity-test">Write a Sanity Test</a></h1>
<p>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.</p>
<p>The test data I'm round tripping are some Futurama quotes I got off the internet
and put in the <code>futurama-quotes.txt</code> file, which is read into a <code>&amp;'static str</code>
at compile time via the <code>include_str!(&quot;../futurama-quotes.txt&quot;)</code> macro
invocation.</p>
<p>Without further ado, here is the test, which should be appended to the bottom of
our <code>src/lib.rs</code> file:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>#[cfg(test)]
mod tests {
use super::*;
use std::mem;
#[test]
fn round_trip_compression_decompression() {
unsafe {
let input = include_str!(&quot;../futurama-quotes.txt&quot;).as_bytes();
let mut compressed_output: Vec&lt;u8&gt; = vec![0; input.len()];
let mut decompressed_output: Vec&lt;u8&gt; = vec![0; input.len()];
// Construct a compression stream.
let mut stream: bz_stream = mem::zeroed();
let result = BZ2_bzCompressInit(&amp;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 _) =&gt; panic!(&quot;BZ_CONFIG_ERROR&quot;),
r if r == (BZ_PARAM_ERROR as _) =&gt; panic!(&quot;BZ_PARAM_ERROR&quot;),
r if r == (BZ_MEM_ERROR as _) =&gt; panic!(&quot;BZ_MEM_ERROR&quot;),
r if r == (BZ_OK as _) =&gt; {},
r =&gt; panic!(&quot;Unknown return value = {}&quot;, 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(&amp;mut stream as *mut _, BZ_FINISH as _);
match result {
r if r == (BZ_RUN_OK as _) =&gt; panic!(&quot;BZ_RUN_OK&quot;),
r if r == (BZ_FLUSH_OK as _) =&gt; panic!(&quot;BZ_FLUSH_OK&quot;),
r if r == (BZ_FINISH_OK as _) =&gt; panic!(&quot;BZ_FINISH_OK&quot;),
r if r == (BZ_SEQUENCE_ERROR as _) =&gt; panic!(&quot;BZ_SEQUENCE_ERROR&quot;),
r if r == (BZ_STREAM_END as _) =&gt; {},
r =&gt; panic!(&quot;Unknown return value = {}&quot;, r),
}
// Finish the compression stream.
let result = BZ2_bzCompressEnd(&amp;mut stream as *mut _);
match result {
r if r == (BZ_PARAM_ERROR as _) =&gt; panic!(&quot;BZ_PARAM_ERROR&quot;),
r if r == (BZ_OK as _) =&gt; {},
r =&gt; panic!(&quot;Unknown return value = {}&quot;, r),
}
// Construct a decompression stream.
let mut stream: bz_stream = mem::zeroed();
let result = BZ2_bzDecompressInit(&amp;mut stream as *mut _,
4, // verbosity (4 = most verbose)
0); // default small factor
match result {
r if r == (BZ_CONFIG_ERROR as _) =&gt; panic!(&quot;BZ_CONFIG_ERROR&quot;),
r if r == (BZ_PARAM_ERROR as _) =&gt; panic!(&quot;BZ_PARAM_ERROR&quot;),
r if r == (BZ_MEM_ERROR as _) =&gt; panic!(&quot;BZ_MEM_ERROR&quot;),
r if r == (BZ_OK as _) =&gt; {},
r =&gt; panic!(&quot;Unknown return value = {}&quot;, 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(&amp;mut stream as *mut _);
match result {
r if r == (BZ_PARAM_ERROR as _) =&gt; panic!(&quot;BZ_PARAM_ERROR&quot;),
r if r == (BZ_DATA_ERROR as _) =&gt; panic!(&quot;BZ_DATA_ERROR&quot;),
r if r == (BZ_DATA_ERROR_MAGIC as _) =&gt; panic!(&quot;BZ_DATA_ERROR&quot;),
r if r == (BZ_MEM_ERROR as _) =&gt; panic!(&quot;BZ_MEM_ERROR&quot;),
r if r == (BZ_OK as _) =&gt; panic!(&quot;BZ_OK&quot;),
r if r == (BZ_STREAM_END as _) =&gt; {},
r =&gt; panic!(&quot;Unknown return value = {}&quot;, r),
}
// Close the decompression stream.
let result = BZ2_bzDecompressEnd(&amp;mut stream as *mut _);
match result {
r if r == (BZ_PARAM_ERROR as _) =&gt; panic!(&quot;BZ_PARAM_ERROR&quot;),
r if r == (BZ_OK as _) =&gt; {},
r =&gt; panic!(&quot;Unknown return value = {}&quot;, r),
}
assert_eq!(input, &amp;decompressed_output[..]);
}
}
}
<span class="boring">}
</span></code></pre></pre>
<p>Now let's run <code>cargo test</code> again and verify that everything is linking and binding
properly!</p>
<pre><code class="language-bash">$ 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 &amp; 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
</code></pre>
<h1><a class="header" href="#publish-your-crate" id="publish-your-crate">Publish Your Crate!</a></h1>
<p>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 <a href="https://crates.io/crates/bzip2-sys"><code>bzip2-sys</code></a> crate providing raw FFI bindings, and there is
already a <a href="https://crates.io/crates/bzip2"><code>bzip2</code></a> crate providing a nice, safe, Rust-y API on top of the
bindings, so we have nothing left to do here!</p>
<p>Check out the <a href="https://github.com/fitzgen/bindgen-tutorial-bzip2-sys">full code on Github!</a></p>
<p>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 <code>hello</code> with two files inside it. A C source file <code>hello.c</code>
containing</p>
<pre><code class="language-c">int hello() {
return 42;
}
</code></pre>
<p>and a C header file <code>hello.h</code> containing</p>
<pre><code class="language-c">int hello();
</code></pre>
<p>Given that the library has not been compiled yet, we need to modify the
<code>build.rs</code> build script to compile the <code>hello.c</code> source file into a static
library:</p>
<pre><code class="language-rust ignore">use std::env;
use std::path::PathBuf;
use bindgen::CargoCallbacks;
fn main() {
// This is the directory where the `c` library is located.
let libdir_path = PathBuf::from(&quot;hello&quot;)
// Canonicalize the path as `rustc-link-search` requires an absolute
// path.
.canonicalize()
.expect(&quot;cannot canonicalize path&quot;);
// This is the path to the `c` headers file.
let headers_path = libdir_path.join(&quot;hello.h&quot;);
let headers_path_str = headers_path.to_str().expect(&quot;Path is not a valid string&quot;);
// This is the path to the intermediate object file for our library.
let obj_path = libdir_path.join(&quot;hello.o&quot;);
// This is the path to the static library file.
let lib_path = libdir_path.join(&quot;libhello.a&quot;);
// Tell cargo to look for shared libraries in the specified directory
println!(&quot;cargo:rustc-link-search={}&quot;, 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!(&quot;cargo:rustc-link-lib=hello&quot;);
// 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(&quot;clang&quot;)
.arg(&quot;-c&quot;)
.arg(&quot;-o&quot;)
.arg(&amp;obj_path)
.arg(libdir_path.join(&quot;hello.c&quot;))
.output()
.expect(&quot;could not spawn `clang`&quot;)
.status
.success()
{
// Panic if the command was not successful.
panic!(&quot;could not compile object file&quot;);
}
// 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(&quot;ar&quot;)
.arg(&quot;rcs&quot;)
.arg(lib_path)
.arg(obj_path)
.output()
.expect(&quot;could not spawn `ar`&quot;)
.status
.success()
{
// Panic if the command was not successful.
panic!(&quot;could not emit library file&quot;);
}
// 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(CargoCallbacks::new()))
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect(&quot;Unable to generate bindings&quot;);
// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from(env::var(&quot;OUT_DIR&quot;).unwrap()).join(&quot;bindings.rs&quot;);
bindings
.write_to_file(out_path)
.expect(&quot;Couldn't write bindings!&quot;);
}
</code></pre>
<h1><a class="header" href="#command-line-usage" id="command-line-usage">Command Line Usage</a></h1>
<p>Install the <code>bindgen</code> executable with <code>cargo</code>:</p>
<pre><code class="language-bash">$ cargo install bindgen-cli
</code></pre>
<p>The <code>bindgen</code> executable is installed to <code>~/.cargo/bin</code>. You have to add that
directory to your <code>$PATH</code> to use <code>bindgen</code>.</p>
<p><code>bindgen</code> 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 <code>stdout</code>.</p>
<p>If we wanted to generated Rust FFI bindings from a C header named <code>input.h</code> and
put them in the <code>bindings.rs</code> file, we would invoke <code>bindgen</code> like this:</p>
<pre><code class="language-bash">$ bindgen input.h -o bindings.rs
</code></pre>
<p>For more details, pass the <code>--help</code> flag:</p>
<pre><code class="language-bash">$ bindgen --help
</code></pre>
<h1><a class="header" href="#customizing-the-generated-bindings" id="customizing-the-generated-bindings">Customizing the Generated Bindings</a></h1>
<p>The translation of classes, structs, enums, and typedefs can be adjusted in a
few ways:</p>
<ol>
<li>
<p>By using the <code>bindgen::Builder</code>'s configuration methods, when using <code>bindgen</code>
as a library.</p>
</li>
<li>
<p>By passing extra flags and options to the <code>bindgen</code> executable.</p>
</li>
<li>
<p>By adding an annotation comment to the C/C++ source code. Annotations are
specially formatted HTML tags inside doxygen style comments:</p>
<ul>
<li>
<p>For single line comments:</p>
<pre><code class="language-c">/// &lt;div rustbindgen&gt;&lt;/div&gt;
</code></pre>
</li>
<li>
<p>For multi-line comments:</p>
<pre><code class="language-c">/**
* &lt;div rustbindgen&gt;&lt;/div&gt;
*/
</code></pre>
</li>
</ul>
</li>
</ol>
<p>We'll leave the nitty-gritty details to
the <a href="https://docs.rs/bindgen">docs.rs API reference</a> and <code>bindgen --help</code>, but
provide higher level concept documentation here.</p>
<h1><a class="header" href="#allowlisting" id="allowlisting">Allowlisting</a></h1>
<p>Allowlisting allows us to be precise about which type, function, and global
variable definitions <code>bindgen</code> 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</p>
<ul>
<li>the generated bindings contain a lot of extra definitions we don't plan on using, or</li>
<li>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</li>
</ul>
<p>If we specify allowlisting rules, then <code>bindgen</code> 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.</p>
<h3><a class="header" href="#library" id="library">Library</a></h3>
<ul>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.allowlist_type"><code>bindgen::Builder::allowlist_type</code></a></li>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.allowlist_function"><code>bindgen::Builder::allowlist_function</code></a></li>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.allowlist_var"><code>bindgen::Builder::allowlist_var</code></a></li>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.allowlist_file"><code>bindgen::Builder::allowlist_file</code></a></li>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.allowlist_item"><code>bindgen::Builder::allowlist_item</code></a></li>
</ul>
<h3><a class="header" href="#command-line" id="command-line">Command Line</a></h3>
<ul>
<li><code>--allowlist-type &lt;type&gt;</code></li>
<li><code>--allowlist-function &lt;function&gt;</code></li>
<li><code>--allowlist-var &lt;var&gt;</code></li>
<li><code>--allowlist-file &lt;path&gt;</code></li>
<li><code>--allowlist-item &lt;item&gt;</code></li>
</ul>
<h3><a class="header" href="#annotations" id="annotations">Annotations</a></h3>
<p>None.</p>
<h1><a class="header" href="#blocklisting" id="blocklisting">Blocklisting</a></h1>
<p>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 <code>UnsafeCell</code>), 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, <a href="./opaque.html">make it opaque</a> instead of
blocklisting it.)</p>
<p>Blocklisted types are pessimistically assumed not to be able to <code>derive</code> any
traits, which can transitively affect other types' ability to <code>derive</code> traits or
not.</p>
<p>The <code>blocklist-file</code> 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.</p>
<h3><a class="header" href="#library-1" id="library-1">Library</a></h3>
<ul>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.blocklist_file"><code>bindgen::Builder::blocklist_file</code></a></li>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.blocklist_function"><code>bindgen::Builder::blocklist_function</code></a></li>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.blocklist_item"><code>bindgen::Builder::blocklist_item</code></a></li>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.blocklist_type"><code>bindgen::Builder::blocklist_type</code></a></li>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.blocklist_var"><code>bindgen::Builder::blocklist_var</code></a></li>
</ul>
<h3><a class="header" href="#command-line-1" id="command-line-1">Command Line</a></h3>
<ul>
<li><code>--blocklist-file &lt;path&gt;</code></li>
<li><code>--blocklist-function &lt;function&gt;</code></li>
<li><code>--blocklist-item &lt;item&gt;</code></li>
<li><code>--blocklist-type &lt;type&gt;</code></li>
<li><code>--blocklist-var &lt;var&gt;</code></li>
</ul>
<h3><a class="header" href="#annotations-1" id="annotations-1">Annotations</a></h3>
<pre><code class="language-cpp">/// &lt;div rustbindgen hide&gt;&lt;/div&gt;
class Foo {
// ...
};
</code></pre>
<h1><a class="header" href="#treating-a-type-as-an-opaque-blob-of-bytes" id="treating-a-type-as-an-opaque-blob-of-bytes">Treating a Type as an Opaque Blob of Bytes</a></h1>
<p>Sometimes a type definition is simply not translatable to Rust, for example it
uses
<a href="https://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error">C++'s SFINAE</a> 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. <code>bindgen</code> will attempt to detect such cases and do this
automatically, but other times it needs some explicit help from you.</p>
<h3><a class="header" href="#library-2" id="library-2">Library</a></h3>
<ul>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.opaque_type"><code>bindgen::Builder::opaque_type</code></a></li>
</ul>
<h3><a class="header" href="#command-line-2" id="command-line-2">Command Line</a></h3>
<ul>
<li><code>--opaque-type &lt;type&gt;</code></li>
</ul>
<h3><a class="header" href="#annotation" id="annotation">Annotation</a></h3>
<pre><code class="language-cpp">/// &lt;div rustbindgen opaque&gt;&lt;/div&gt;
class Foo {
// ...
};
</code></pre>
<h1><a class="header" href="#replacing-one-type-with-another" id="replacing-one-type-with-another">Replacing One Type with Another</a></h1>
<p>The <code>replaces</code> 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.</p>
<p>For example, in a C++ header:</p>
<pre><code class="language-cpp">/**
* &lt;div rustbindgen replaces=&quot;nsTArray&quot;&gt;&lt;/div&gt;
*/
template&lt;typename T&gt;
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() {};
};
</code></pre>
<p>That way, after code generation, the bindings for the <code>nsTArray</code> type are
the ones that would be generated for <code>nsTArray_Simple</code>.</p>
<p>Replacing is only available as an annotation. To replace a C or C++ definition
with a Rust definition, use <a href="./blocklisting.html">blocklisting</a>.</p>
<h1><a class="header" href="#preventing-the-derivation-of-copy-and-clone" id="preventing-the-derivation-of-copy-and-clone">Preventing the Derivation of <code>Copy</code> and <code>Clone</code></a></h1>
<p><code>bindgen</code> will attempt to derive the <code>Copy</code> and <code>Clone</code> traits on a best-effort
basis. Sometimes, it might not understand that although adding <code>#[derive(Copy, Clone)]</code> to a translated type definition will compile, it still shouldn't do
that for reasons it can't know. In these cases, the <code>nocopy</code> annotation can be
used to prevent bindgen to autoderive the <code>Copy</code> and <code>Clone</code> traits for a type.</p>
<h3><a class="header" href="#library-3" id="library-3">Library</a></h3>
<ul>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.no_copy"><code>bindgen::Builder::no_copy</code></a></li>
</ul>
<h3><a class="header" href="#command-line-3" id="command-line-3">Command Line</a></h3>
<ul>
<li><code>--no-copy &lt;regex&gt;</code></li>
</ul>
<h3><a class="header" href="#annotations-2" id="annotations-2">Annotations</a></h3>
<pre><code class="language-c">/**
* Although bindgen can't know, this struct is not safe to move because pthread
* mutexes can't move in memory!
*
* &lt;div rustbindgen nocopy&gt;&lt;/div&gt;
*/
struct MyMutexWrapper {
pthread_mutex_t raw;
// ...
};
</code></pre>
<h1><a class="header" href="#preventing-the-derivation-of-debug" id="preventing-the-derivation-of-debug">Preventing the Derivation of <code>Debug</code></a></h1>
<p><code>bindgen</code> will attempt to derive the <code>Debug</code> traits on a best-effort
basis. Sometimes, it might not understand that although adding <code>#[derive(Debug)]</code> to a translated type definition will compile, it still shouldn't do
that for reasons it can't know. In these cases, the <code>nodebug</code> annotation can be
used to prevent bindgen to autoderive the <code>Debug</code> traits for a type.</p>
<h3><a class="header" href="#library-4" id="library-4">Library</a></h3>
<ul>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.no_debug"><code>bindgen::Builder::no_debug</code></a></li>
</ul>
<h3><a class="header" href="#command-line-4" id="command-line-4">Command Line</a></h3>
<ul>
<li><code>--no-debug &lt;regex&gt;</code></li>
</ul>
<h3><a class="header" href="#annotations-3" id="annotations-3">Annotations</a></h3>
<pre><code class="language-c">/**
* 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:
*
* &lt;div rustbindgen nodebug&gt;&lt;/div&gt;
*/
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);
</code></pre>
<h1><a class="header" href="#preventing-the-derivation-of-default" id="preventing-the-derivation-of-default">Preventing the Derivation of <code>Default</code></a></h1>
<p><code>bindgen</code> will attempt to derive/impl the <code>Default</code> traits on a best-effort basis.
Sometimes, we need customize the implement of <code>Default</code> for certain types,
In these cases, the <code>nodefault</code> annotation can be used to prevent bindgen
to autoderive the <code>Default</code> traits for a type.</p>
<h3><a class="header" href="#library-5" id="library-5">Library</a></h3>
<ul>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.no_default"><code>bindgen::Builder::no_default</code></a></li>
</ul>
<h3><a class="header" href="#command-line-5" id="command-line-5">Command Line</a></h3>
<ul>
<li><code>--no-default &lt;regex&gt;</code></li>
</ul>
<h3><a class="header" href="#annotations-4" id="annotations-4">Annotations</a></h3>
<pre><code class="language-c">/**
* We need to specify some preset values as the Default of Header.
*
* for example:
*
* &lt;div rustbindgen nodefault&gt;&lt;/div&gt;
*/
struct Header {
unsigned int magic;
unsigned char data[252];
};
...
</code></pre>
<h3><a class="header" href="#customize-implements" id="customize-implements">Customize Implements</a></h3>
<pre><code class="language-rust ignore">// Include the generated bindings.
include!(concat!(env!(&quot;OUT_DIR&quot;), &quot;/bindings.rs&quot;));
impl Default for Header {
fn default() -&gt; Self {
Self {
magic: 0x10203040u32,
data: [0; 252usize],
}
}
}
</code></pre>
<h1><a class="header" href="#annotating-types-with-must-use" id="annotating-types-with-must-use">Annotating types with <code>#[must-use]</code></a></h1>
<p><code>bindgen</code> can be instructed to annotate certain types with
<a href="https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"><code>#[must_use]</code></a>.</p>
<p>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 <code>#[must_use]</code> to this type, so the Rust
compiler emits a warning when the check is missing.</p>
<h3><a class="header" href="#library-6" id="library-6">Library</a></h3>
<ul>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.must_use_type"><code>bindgen::Builder::must_use_type</code></a></li>
</ul>
<h3><a class="header" href="#command-line-6" id="command-line-6">Command Line</a></h3>
<ul>
<li><code>--must-use-type &lt;regex&gt;</code></li>
</ul>
<h3><a class="header" href="#annotations-5" id="annotations-5">Annotations</a></h3>
<pre><code class="language-c">/** &lt;div rustbindgen mustusetype&gt;&lt;/div&gt; */
struct ErrorType {
// ...
};
...
</code></pre>
<h1><a class="header" href="#making-fields-private" id="making-fields-private">Making fields private</a></h1>
<p>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.</p>
<h3><a class="header" href="#annotation-1" id="annotation-1">Annotation</a></h3>
<pre><code class="language-c">struct OneFieldPrivate {
/** Null-terminated, static string. &lt;div rustbindgen private&gt; */
const char *s;
bool b;
};
/** &lt;div rustbindgen private&gt; */
struct MostFieldsPrivate {
int a;
bool b;
/** &lt;div rustbindgen private=&quot;false&quot;&gt;&lt;/div&gt; */
char c;
};
</code></pre>
<p>Then in Rust:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">#[repr(C)]
</span><span class="boring">pub struct OneFieldPrivate {
</span><span class="boring"> s: *const ::std::os::raw::c_char,
</span><span class="boring"> pub b: bool,
</span><span class="boring">}
</span>
impl OneFieldPrivate {
pub fn new(s: &amp;'static std::ffi::CStr, b: bool) -&gt; Self {
OneFieldPrivate { s: s.as_ptr(), b }
}
}
<span class="boring">}
</span></code></pre></pre>
<h1><a class="header" href="#code-formatting" id="code-formatting">Code Formatting</a></h1>
<p><code>bindgen</code> uses <code>rustfmt</code> to format the emitted bindings. This section describes
how to adjust the <code>rustfmt</code> behavior when being used from <code>bindgen</code>.</p>
<h2><a class="header" href="#passing-a-rustfmttoml-configuration-file" id="passing-a-rustfmttoml-configuration-file">Passing a <code>rustfmt.toml</code> configuration file</a></h2>
<p><code>rustfmt</code> should automatically use any <code>rustfmt.toml</code> file that is present in
the directory from where <code>bindgen</code> 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 <code>--rustfmt-configuration-file</code> flag or the
<a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.rustfmt_configuration_file"><code>Builder::rustfmt_configuration_file</code></a>
method.</p>
<h2><a class="header" href="#using-a-nightly-release-of-rustfmt" id="using-a-nightly-release-of-rustfmt">Using a nightly release of <code>rustfmt</code></a></h2>
<p>If the <code>rustfmt</code> command does not correspond to a nightly release of <code>rustfmt</code>
but you have <code>rustup</code> available, you can use <code>nightly</code> by following these
steps:</p>
<h3><a class="header" href="#when-using-bindgen-as-a-cli-application" id="when-using-bindgen-as-a-cli-application">When using <code>bindgen</code> as a CLI application</a></h3>
<p>Use <code>rustup run</code> to run <code>bindgen</code>:</p>
<pre><code class="language-bash">$ rustup run nightly bindgen [ARGS]
</code></pre>
<h3><a class="header" href="#when-using-bindgen-as-a-library" id="when-using-bindgen-as-a-library">When using <code>bindgen</code> as a library</a></h3>
<p>Take the output of the following command:</p>
<pre><code class="language-bash">$ rustup which rustfmt --toolchain=nightly
</code></pre>
<p>and pass it to
<a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.with_rustfmt"><code>Builder::with_rustfmt</code></a>:</p>
<pre><code class="language-rust ignore">use bindgen::Builder;
use std::process::Command;
fn main() {
let output = Command::new(&quot;rustup&quot;)
.args([&quot;which&quot;, &quot;rustfmt&quot;, &quot;--toolchain&quot;, &quot;nightly&quot;])
.output()
.expect(&quot;Could not spawn `rustup` command&quot;);
assert!(
output.status.success(),
&quot;Unsuccessful status code when running `rustup`: {:?}&quot;,
output
);
let rustfmt_path =
String::from_utf8(output.stdout).expect(&quot;The `rustfmt` path is not valid `utf-8`&quot;);
let bindings = Builder::default()
.header(&quot;path/to/input.h&quot;)
.with_rustfmt(rustfmt_path)
.generate()
.expect(&quot;Could not generate bindings&quot;);
bindings
.write_to_file(&quot;path/to/output.rs&quot;)
.expect(&quot;Could not write bindings&quot;);
}
</code></pre>
<p>These two methods also apply to any other toolchain available in your system.</p>
<h2><a class="header" href="#using-prettyplease" id="using-prettyplease">Using <code>prettyplease</code></a></h2>
<p>The <a href="https://github.com/dtolnay/prettyplease"><code>prettyplease</code></a> crate is a
minimal formatter for generated code. To format bindings using <code>prettyplease</code>
you have to invoke <code>bindgen</code> with either the <code>--formatter=prettyplease</code> flag or
the <code>bindgen::Builder::formatter(bindgen::Formatter::Prettyplease)</code>. One of
its advantages is that <code>prettyplease</code> can be used in minimal environments where
the Rust toolchain is not installed.</p>
<h2><a class="header" href="#how-can-i-normalize-doc-attributes" id="how-can-i-normalize-doc-attributes">How can I normalize <code>#[doc]</code> attributes?</a></h2>
<p><code>bindgen</code> emits all the documentation using <code>#[doc]</code> attributes by default. If
you want to use the more user-friendly <code>///</code> syntax, you have two options:</p>
<h3><a class="header" href="#use-rustfmt" id="use-rustfmt">Use <code>rustfmt</code></a></h3>
<p><code>rustfmt</code> can be configured to normalize documentation. To do so, you have to
create a <code>rustfmt.toml</code> file with the following contents:</p>
<pre><code class="language-toml">normalize_doc_attributes = true
</code></pre>
<p>Then, you have set up <code>bindgen</code> so it passes this file to <code>rustfmt</code>. Given that
the <code>normalize_doc_attributes</code> option is
<a href="https://github.com/rust-lang/rustfmt/issues/3351">unstable</a>, you also have to
set up bindgen to use a <code>nightly</code> release of <code>rustfmt</code>.</p>
<h3><a class="header" href="#use-prettyplease" id="use-prettyplease">Use <code>prettyplease</code></a></h3>
<p><code>prettyplease</code> normalizes documentation without any additional configuration.
Then you just have to tell <code>bindgen</code> to use <code>prettyplease</code> as the code
formatter.</p>
<h1><a class="header" href="#generating-bindings-to-c" id="generating-bindings-to-c">Generating Bindings to C++</a></h1>
<p><code>bindgen</code> can handle some C++ features, but not all of them. To set
expectations: <code>bindgen</code> 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.</p>
<p>When passing in header files, the file will automatically be treated as C++ if
it ends in <code>.hpp</code>. If it doesn't, adding <code>-x c++</code> clang args can be used to
force C++ mode. You probably also want to use <code>-std=c++14</code> or similar clang args
as well.</p>
<p>You pretty much <strong>must</strong> use <a href="./allowlisting.html">allowlisting</a> when working
with C++ to avoid pulling in all of the <code>std::.*</code> types, many of which <code>bindgen</code>
cannot handle. Additionally, you may want to mark other types as
<a href="./opaque.html">opaque</a> that <code>bindgen</code> stumbles on. It is recommended to mark
all of <code>std::.*</code> opaque, and to allowlist only precisely the functions and types
you intend to use.</p>
<p>You should read up on the <a href="./faq.html">FAQs</a> as well.</p>
<h2><a class="header" href="#supported-features" id="supported-features">Supported Features</a></h2>
<ul>
<li>
<p>Inheritance (for the most part; there are
<a href="https://github.com/rust-lang/rust-bindgen/issues/380">some outstanding bugs</a>)</p>
</li>
<li>
<p>Methods</p>
</li>
<li>
<p>Bindings to constructors and destructors (but they aren't implicitly or
automatically invoked)</p>
</li>
<li>
<p>Function and method overloading</p>
</li>
<li>
<p>Templates <em>without</em> specialization. You should be able to access individual
fields of the class or struct.</p>
</li>
</ul>
<h2><a class="header" href="#unsupported-features" id="unsupported-features">Unsupported Features</a></h2>
<p>When <code>bindgen</code> 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</p>
<ol>
<li>
<p>we should always get layout, size, and alignment correct, and</p>
</li>
<li>
<p>just because one type uses specialization, that shouldn't cause <code>bindgen</code> to
give up on everything else.</p>
</li>
</ol>
<p>Without further ado, here are C++ features that <code>bindgen</code> does not support or
cannot translate into Rust:</p>
<ul>
<li>
<p>Inline functions and methods: see
<a href="./faq.html#why-isnt-bindgen-generating-bindings-to-inline-functions">&quot;Why isn't <code>bindgen</code> generating bindings to inline functions?&quot;</a></p>
</li>
<li>
<p>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.</p>
</li>
<li>
<p>Anything related to template specialization:</p>
<ul>
<li>Partial template specialization</li>
<li>Traits templates</li>
<li>Substitution Failure Is Not An Error (SFINAE)</li>
</ul>
</li>
<li>
<p>Cross language inheritance, for example inheriting from a Rust struct in C++.</p>
</li>
<li>
<p>Automatically calling copy and/or move constructors or destructors. Supporting
this isn't possible with Rust's move semantics.</p>
</li>
<li>
<p>Exceptions: if a function called through a <code>bindgen</code>-generated interface
raises an exception that is not caught by the function itself, this will
generate undefined behaviour. See
<a href="https://github.com/rust-lang/rust-bindgen/issues/1208">the tracking issue for exceptions</a>
for more details.</p>
</li>
<li>
<p>Many C++ specific aspects of calling conventions. For example in the Itanium abi types that are
&quot;<a href="https://itanium-cxx-abi.github.io/cxx-abi/abi.html#non-trivial">non trivial for the purposes of calls</a>&quot;
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 &quot;hidden parameter&quot;, 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 <a href="https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170#return-values">x64 calling convention</a>).
Because bindgen does not know about these rules generated interfaces using such types are currently invalid.</p>
</li>
</ul>
<h2><a class="header" href="#constructor-semantics" id="constructor-semantics">Constructor semantics</a></h2>
<p><code>bindgen</code> will generate a wrapper for any class constructor declared in the
input headers. For example, this headers file</p>
<pre><code class="language-c++">class MyClass {
public:
MyClass();
void method();
};
</code></pre>
<p>Will produce the following code:</p>
<pre><code class="language-rust ignore">#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct MyClass {
pub _address: u8,
}
extern &quot;C&quot; {
#[link_name = &quot;\u{1}_ZN7MyClass6methodEv&quot;]
pub fn MyClass_method(this: *mut MyClass);
}
extern &quot;C&quot; {
#[link_name = &quot;\u{1}_ZN7MyClassC1Ev&quot;]
pub fn MyClass_MyClass(this: *mut MyClass);
}
impl MyClass {
#[inline]
pub unsafe fn method(&amp;mut self) {
MyClass_method(self)
}
#[inline]
pub unsafe fn new() -&gt; Self {
let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit();
MyClass_MyClass(__bindgen_tmp.as_mut_ptr());
__bindgen_tmp.assume_init()
}
}
</code></pre>
<p>This <code>MyClass::new</code> Rust method can be used as a substitute for the <code>MyClass</code>
C++ constructor. However, the address of the value from inside the method will
be different than from the outside. This is because the <code>__bindgen_tmp</code> value
is moved when the <code>MyClass::new</code> method returns.</p>
<p>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
<code>MyClass_MyClass</code> binding directly instead of the <code>MyClass::new</code> method.</p>
<p>In other words, the Rust equivalent for the following C++ code</p>
<pre><code class="language-c++">MyClass instance = MyClass();
instance.method();
</code></pre>
<p>is not this</p>
<pre><code class="language-rust ignore">let instance = MyClass::new();
instance.method();
</code></pre>
<p>but this</p>
<pre><code class="language-rust ignore">let instance = std::mem::MaybeUninit::&lt;MyClass&gt;::uninit();
MyClass_MyClass(instance.as_mut_ptr());
instance.assume_init_mut().method();
</code></pre>
<p>You can easily verify this fact if you provide a implementation for <code>MyClass</code>
and <code>method</code> that prints the <code>this</code> 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.</p>
<h1><a class="header" href="#generating-bindings-to-objective-c" id="generating-bindings-to-objective-c">Generating Bindings to Objective-C</a></h1>
<p><code>bindgen</code> does not (yet) have full objective-c support but it can generate bindings
for a lot of the apple frameworks without too much blocklisting.</p>
<p>In order to generate bindings, you will need <code>-x objective-c</code> as the clang
args. If you'd like to use <a href="https://crates.io/crates/block">block</a> you will need
<code>-fblocks</code> as a clang arg as well.</p>
<p>Depending on your setup, you may need <code>--generate-block</code> to generate the block
function aliases and <code>--block-extern-crate</code> to insert a <code>extern crate block</code> at
the beginning of the generated bindings. The same logic applies to the
<code>--objc-extern-crate</code> parameter.</p>
<p>The objective-c classes will be represented as a <code>struct Foo(id)</code> and a trait
<code>IFoo</code> where <code>Foo</code> is the objective-c class and <code>id</code> is an alias for <code>*mut objc::runtime::Object</code> (the pointer to the objective-c instance). The trait
<code>IFoo</code> is needed to allow for the generated inheritance.</p>
<p>Functions that use or return objective-c pointers of instance <code>Foo</code> will return
<code>Foo</code>. The reason this works is because <code>Foo</code> represented as <code>transparent</code>.
This will be helpful for a lot of objective-c frameworks however there are some
cases where functions return <code>instancetype</code> which is a type alias for <code>id</code> so
an occasional <code>foo.0</code> may be required. An example of this would in the UIKit
framework should you want to add a <code>UILabel</code> to a
<a href="https://developer.apple.com/documentation/uikit/uistackview/1616227-addarrangedsubview?language=objc">UIStackView</a>
you will need to convert the <code>UILabel</code> to a <code>UIView</code> via <code>UIView(label.0)</code>.</p>
<p>Each class (struct) has an <code>alloc</code> and a <code>dealloc</code> to match that of some of the alloc
methods found in <code>NSObject</code>.</p>
<p>In order to initialize a class <code>Foo</code>, you will have to do something like <code>let foo = Foo(Foo::alloc().initWithStuff())</code>.</p>
<p>To blocklist an Objective-C method, you should add the bindgen generated method
path (e.g. <code>IFoo::method</code> or <code>IFoo::class_method</code>) as a blocklist item.</p>
<h2><a class="header" href="#supported-features-1" id="supported-features-1">Supported Features</a></h2>
<ul>
<li>Inheritance matched to rust traits with prefixes of <code>I</code> which
stands for interface.</li>
<li>Protocols which match to rust traits with prefixes of <code>P</code> which
stands for Protocol.</li>
<li>Classes will generate <code>struct Foo(id)</code> where <code>Foo</code> is the class
name and <code>id</code> is a pointer to the objective-c Object.</li>
<li>Blocks</li>
</ul>
<h2><a class="header" href="#useful-notes" id="useful-notes">Useful Notes</a></h2>
<ul>
<li>If you're targeting <code>aarch64-apple-ios</code>, you'll need to have the clang arg
<code>--target=arm64-apple-ios</code> as mentioned
<a href="https://github.com/rust-lang/rust-bindgen/issues/1211#issuecomment-569804287">here</a>.</li>
<li>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 <code>time.h</code> as has a variable called timezone that
conflicts with some of the things in <code>NSCalendar.h</code>.</li>
<li>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
<a href="https://github.com/rust-lang/rust-bindgen/issues/1705">here</a>.</li>
<li>instancetype return methods does not return <code>Self</code> for you given class, it
returns a <code>mut * objc::runtime::Objc</code> which is aliased as <code>id</code>. This is because
objective-c's inheritance doesn't perfectly match that of rusts.</li>
<li>Depending on what you're trying <code>bindgen</code> against, you may end up including
all of Core Foundation and any other frameworks. This will result in a very
long compile time.</li>
</ul>
<h2><a class="header" href="#not-yet-supported" id="not-yet-supported">Not (yet) Supported</a></h2>
<ul>
<li>Nullability attributes which return <code>Option</code>s.</li>
<li>Probably many other things. Feel free to <a href="https://github.com/rust-lang/rust-bindgen/issues">open an issue</a>.</li>
</ul>
<h1><a class="header" href="#example-crates" id="example-crates">Example crate(s)</a></h1>
<ul>
<li><a href="https://github.com/simlay/uikit-sys">uikit-sys</a></li>
</ul>
<h1><a class="header" href="#using-the-union-types-generated-by-bindgen" id="using-the-union-types-generated-by-bindgen">Using the Union Types Generated by Bindgen</a></h1>
<p><strong>NOTE</strong>: Rust 1.19 stabilized the <code>union</code> type (see Rust issue <a href="https://github.com/rust-lang/rust/issues/32836">#32836</a>).</p>
<p>You can pass the <code>--rust-target</code> option to tell <code>bindgen</code> to target a specific version of Rust.
By default, <code>bindgen</code> will target the latest stable Rust.
The <code>--rust-target</code> option accepts a specific stable version (such as &quot;1.0&quot; or &quot;1.19&quot;) or &quot;nightly&quot;.</p>
<p><strong>NOTE</strong>: The <code>--unstable-rust</code> option is deprecated; use <code>--rust-target nightly</code> instead.</p>
<p>In general, most interactions with unions (either reading or writing) are unsafe, meaning you must surround union accesses in an <code>unsafe {}</code> block.</p>
<p>For this discussion, we will use the following C type definitions:</p>
<pre><code class="language-c">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;
</code></pre>
<h2><a class="header" href="#relevant-bindgen-options" id="relevant-bindgen-options">Relevant Bindgen Options</a></h2>
<h3><a class="header" href="#library-7" id="library-7">Library</a></h3>
<ul>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.rust_target"><code>bindgen::Builder::rust_target()</code></a> <!-- Update when live --></li>
<li><a href="https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.derive_default"><code>bindgen::Builder::derive_default()</code></a></li>
</ul>
<h3><a class="header" href="#command-line-7" id="command-line-7">Command Line</a></h3>
<ul>
<li><code>--rust-target</code></li>
<li><code>--with-derive-default</code></li>
</ul>
<h2><a class="header" href="#which-union-type-will-bindgen-generate" id="which-union-type-will-bindgen-generate">Which union type will Bindgen generate?</a></h2>
<p>Bindgen can emit one of two Rust types that correspond to C unions:</p>
<ul>
<li>Rust's <code>union</code> builtin (only available in Rust &gt;= 1.19, including nightly)</li>
<li>Bindgen's <code>BindgenUnion</code> (available for all Rust targets)</li>
</ul>
<p>Bindgen uses the following logic to determine which Rust union type to emit:</p>
<ul>
<li>If the Rust target is &gt;= 1.19 (including nightly) AND each field of the union can derive <code>Copy</code>, then generate a <code>union</code> builtin.</li>
<li>Otherwise, generate a <code>BindgenUnion</code>.</li>
</ul>
<h2><a class="header" href="#using-the-union-builtin" id="using-the-union-builtin">Using the <code>union</code> builtin</a></h2>
<p>When using the <code>union</code> builtin type, there are two choices for initialization:</p>
<ol>
<li>Zero</li>
<li>With a specific variant</li>
</ol>
<pre><code class="language-rust ignore">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::&lt;bindings_builtin_union::greek_t&gt;() };
// 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!(&quot;{:?}&quot;, z.alfa); // alpha_t { a: 1, b: -1 }
println!(&quot;{:?}&quot;, z.bravo); // beta_t { c: 1, d: 65535, e: 65535, f: 127 }
}
}
</code></pre>
<h2><a class="header" href="#using-the-bindgenunion-type" id="using-the-bindgenunion-type">Using the <code>BindgenUnion</code> type</a></h2>
<p>If the target Rust version does not support the new <code>union</code> type or there is a field that cannot derive <code>Copy</code>, then bindgen will provide union-like access to a <code>struct</code>.</p>
<p>Interacting with these unions is slightly different than the new <code>union</code> types.
You must access union variants through a reference.</p>
<pre><code class="language-rust ignore">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!(&quot;{:?}&quot;, x.alfa.as_ref()); // alpha_t { a: 1, b: -1 }
println!(&quot;{:?}&quot;, x.bravo.as_ref()); // beta_t { c: 1, d: 65535, e: 65535, f: 0 }
}
</code></pre>
<p>If you attempt to access a <code>BindgenUnion</code> field directly, you will see errors like this:</p>
<pre><code class="language-text">error[E0308]: mismatched types
--&gt; 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&lt;bindings::alpha_t&gt;`
found type `bindings::alpha_t`
</code></pre>
<h1><a class="header" href="#using-the-bitfield-types-generated-by-bindgen" id="using-the-bitfield-types-generated-by-bindgen">Using the Bitfield Types Generated by Bindgen</a></h1>
<h2><a class="header" href="#bitfield-strategy-overview" id="bitfield-strategy-overview">Bitfield Strategy Overview</a></h2>
<p>As Rust does not support bitfields, Bindgen generates a struct for each with the following characteristics</p>
<ul>
<li>Immutable getter functions for each bitfield named <code>&lt;bitfield&gt;</code></li>
<li>Setter functions for each contiguous block of bitfields named <code>set_&lt;bitfield&gt;</code></li>
<li>For each contiguous block of bitfields, Bindgen emits an opaque physical field that contains one or more logical bitfields</li>
<li>A static constructor <code>new_bitfield_{1, 2, ...}</code> with a parameter for each bitfield contained within the opaque physical field.</li>
</ul>
<h2><a class="header" href="#bitfield-examples" id="bitfield-examples">Bitfield examples</a></h2>
<p>For this discussion, we will use the following C type definitions and functions.</p>
<pre><code class="language-c">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);
</code></pre>
<p>Bindgen creates a set of field getters and setters for interacting with the bitset. For example, </p>
<pre><code class="language-rust ignore"> let mut bfield = unsafe { create_bitfield() };
bfield.set_a(1);
println!(&quot;a set to {}&quot;, bfield.a());
bfield.set_b(1);
println!(&quot;b set to {}&quot;, bfield.b());
bfield.set_c(3);
println!(&quot;c set to {}&quot;, bfield.c());
unsafe { print_bitfield(bfield) };
</code></pre>
<p>will print out</p>
<pre><code class="language-text">a set to 1
b set to 1
c set to 3
StructWithBitfields: a:1, b:1, c:3
</code></pre>
<p>Overflowing a bitfield will result in the same behavior as in C/C++: the bitfield will be set to 0.</p>
<pre><code class="language-rust ignore"> let mut bfield = unsafe { create_bitfield() };
bfield.set_a(1);
bfield.set_b(1);
bfield.set_c(12);
println!(&quot;c set to {} due to overflow&quot;, bfield.c());
unsafe { print_bitfield(bfield) };
</code></pre>
<p>will print out</p>
<pre><code class="language-text">c set to 0 due to overflow
StructWithBitfields: a:1, b:1, c:0
</code></pre>
<p>To create a new bitfield in Rust, use the bitfield allocation unit constructor.</p>
<p>Note: This requires the Builder's derive_default to be set to true, otherwise the necessary Default functions won't be generated.</p>
<pre><code class="language-rust ignore"> let bfield = StructWithBitfields{
_bitfield_1: StructWithBitfields::new_bitfield_1(0,0,0),
..Default::default()
};
unsafe { print_bitfield(bfield) };
</code></pre>
<p>This will print out</p>
<pre><code class="language-text">StructWithBitfields: a:0, b:0, c:0
</code></pre>
<h1><a class="header" href="#using-c-structures-with-flexible-array-members" id="using-c-structures-with-flexible-array-members">Using C structures with Flexible Array Members</a></h1>
<p>Since time immemorial, C programmers have been using what was called &quot;the struct
hack&quot;. This is a technique for packing a fixed-size structure and a
variable-sized tail within the same memory allocation. Typically this looks
like:</p>
<pre><code class="language-c">struct MyRecord {
time_t timestamp;
unsigned seq;
size_t len;
char payload[0];
};
</code></pre>
<p>Because this is so useful, it was standardized in C99 as &quot;flexible array
members&quot;, using almost identical syntax:</p>
<pre><code class="language-c">struct MyRecord {
time_t timestamp;
unsigned seq;
size_t len;
char payload[]; // NOTE: empty []
};
</code></pre>
<p>Bindgen supports these structures in two different ways.</p>
<h2><a class="header" href="#__incompletearrayfield" id="__incompletearrayfield"><code>__IncompleteArrayField</code></a></h2>
<p>By default, bindgen will generate the corresponding Rust structure:</p>
<pre><code class="language-rust ignore">#[repr(C)]
struct MyRecord {
pub timestamp: time_t,
pub seq: ::std::os::raw::c_uint,
pub len: usize,
pub payload: __IncompleteArrayField&lt;::std::os::raw::c_char&gt;,
}
</code></pre>
<p>The <code>__IncompleteArrayField</code> type is zero-sized, so this structure represents
the prefix without any trailing data. In order to access that data, it provides
the <code>as_slice</code> unsafe method:</p>
<pre><code class="language-rust ignore"> // SAFETY: there's at least `len` bytes allocated and initialized after `myrecord`
let payload = unsafe { myrecord.payload.as_slice(myrecord.len) };
</code></pre>
<p>There's also <code>as_mut_slice</code> which does the obvious.</p>
<p>These are <code>unsafe</code> simply because it's up to you to provide the right length (in
elements of whatever type <code>payload</code> is) as there's no way for Rust or Bindgen to
know. In this example, the length is a very straightforward <code>len</code> field in the
structure, but it could be encoded in any number of ways within the structure,
or come from somewhere else entirely.</p>
<p>One big caveat with this technique is that <code>std::mem::size_of</code> (or
<code>size_of_val</code>) will <em>only</em> 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.</p>
<h2><a class="header" href="#using-dynamically-sized-types" id="using-dynamically-sized-types">Using Dynamically Sized Types</a></h2>
<p>If you invoke bindgen with the <code>--flexarray-dst</code> option, it will generate
something not quite like this:</p>
<pre><code class="language-rust ignore">#[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],
}
</code></pre>
<p>Rust has a set of types which are almost exact analogs for these Flexible Array
Member types: the Dynamically Sized Type (&quot;DST&quot;).</p>
<p>This looks almost identical to a normal Rust structure, except that you'll note
the type of the <code>payload</code> field is a raw slice <code>[...]</code> rather than the usual
reference to slice <code>&amp;[...]</code>.</p>
<p>That <code>payload: [c_char]</code> is telling Rust that it can't directly know the total
size of this structure - the <code>payload</code> field takes an amount of space that's
determined at runtime. This means you can't directly use values of this type,
only references: <code>&amp;MyRecord</code>.</p>
<p>In practice, this is very awkward. So instead, bindgen generates:</p>
<pre><code class="language-rust ignore">#[repr(C)]
struct MyRecord&lt;FAM: ?Sized = [::std::os::raw::c_char; 0]&gt; {
pub timestamp: time_t,
pub seq: ::std::os::raw::c_uint,
pub len: usize,
pub payload: FAM,
}
</code></pre>
<p>That is:</p>
<ol>
<li>a type parameter <code>FAM</code> which represents the type of the <code>payload</code> field,</li>
<li>it's <code>?Sized</code> meaning it can be unsized (ie, a DST)</li>
<li>it has the default type of <code>[c_char; 0]</code> - that is a zero-sized array of characters</li>
</ol>
<p>This means that referencing plain <code>MyRecord</code> will be exactly like <code>MyRecord</code>
with <code>__IncompleteArrayField</code>: it is a fixed-sized structure which you can
manipulate like a normal Rust value.</p>
<p>But how do you get to the DST part?</p>
<p>Bindgen will also implement a set of helper methods for this:</p>
<pre><code class="language-rust ignore">// Static sized variant
impl MyRecord&lt;[::std::os::raw::c_char; 0]&gt; {
pub unsafe fn flex_ref(&amp;self, len: usize) -&gt; &amp;MyRecord&lt;[::std::os::raw::c_char]&gt; { ... }
pub unsafe fn flex_mut_ref(&amp;mut self, len: usize) -&gt; &amp;mut MyRecord&lt;[::std::os::raw::c_char]&gt; { ... }
// And some raw pointer variants
}
</code></pre>
<p>These will take a sized <code>MyRecord&lt;[c_char; 0]&gt;</code> and a length in elements, and
return a reference to a DST <code>MyRecord&lt;[c_char]&gt;</code> where the <code>payload</code> field is a
fully usable slice of <code>len</code> characters.</p>
<p>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
<code>payload</code> field like any other Rust slice.</p>
<p>It also means that doing <code>mem::size_of_val(myrecord)</code> will return the <em>complete</em>
size of this structure, including the suffix.</p>
<p>You can go the other way:</p>
<pre><code class="language-rust ignore">// Dynamic sized variant
impl MyRecord&lt;[::std::os::raw::c_char]&gt; {
pub fn fixed(&amp;self) -&gt; (&amp;MyRecord&lt;[::std::os::raw::c_char; 0]&gt;, usize) { ... }
pub fn fixed_mut(&amp;mut self) -&gt; (&amp;mut MyRecord&lt;[::std::os::raw::c_char; 0]&gt;, usize) { ... }
pub fn layout(len: usize) -&gt; std::alloc::Layout { ... }
}
</code></pre>
<p>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 <code>&amp;self</code> reference.</p>
<p>The <code>layout</code> function takes a length and returns the <code>Layout</code> - that is, size
and alignment, so that you can allocate memory for the structure (for example,
using <code>malloc</code> so you can pass it to a C function).</p>
<p>Unfortunately the language features needed to support these methods are still unstable:</p>
<ul>
<li><a href="https://doc.rust-lang.org/beta/unstable-book/library-features/ptr-metadata.html">ptr_metadata</a>,
which enables all the fixed&lt;-&gt;DST conversions, and</li>
<li><a href="https://doc.rust-lang.org/beta/unstable-book/library-features/layout-for-ptr.html">layout_for_ptr</a>,
which allows he <code>layout</code> method</li>
</ul>
<p>As a result, if you don't specify <code>--rust-target nightly</code> you'll just get the
bare type definitions, but no real way to use them. It's often convenient to add
the</p>
<pre><code class="language-bash">--raw-line '#![feature(ptr_metadata,layout_for_ptr)]'
</code></pre>
<p>option if you're generating Rust as a stand-alone crate. Otherwise you'll need
to add the feature line to your containing crate.</p>
<h1><a class="header" href="#frequently-asked-questions" id="frequently-asked-questions">Frequently Asked Questions</a></h1>
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
<ul>
<li><a href="faq.html#why-isnt-bindgen-generating-methods-for-this-allowlisted-class">Why isn't <code>bindgen</code> generating methods for this allowlisted class?</a></li>
<li><a href="faq.html#why-isnt-bindgen-generating-bindings-to-inline-functions">Why isn't <code>bindgen</code> generating bindings to inline functions?</a></li>
<li><a href="faq.html#does-bindgen-support-the-c-standard-template-library-stl">Does <code>bindgen</code> support the C++ Standard Template Library (STL)?</a></li>
<li><a href="faq.html#how-to-deal-with-bindgen-generated-padding-fields">How to deal with bindgen generated padding fields?</a></li>
<li><a href="faq.html#how-to-generate-bindings-for-a-custom-target">How to generate bindings for a custom target?</a></li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<h3><a class="header" href="#why-isnt-bindgen-generating-methods-for-this-allowlisted-class" id="why-isnt-bindgen-generating-methods-for-this-allowlisted-class">Why isn't <code>bindgen</code> generating methods for this allowlisted class?</a></h3>
<p>Are the methods <code>inline</code> methods, or defined inline in the class? For example:</p>
<pre><code class="language-c++">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;
}
</code></pre>
<p>If so, see
<a href="faq.html#why-isnt-bindgen-generating-bindings-to-inline-functions">&quot;Why isn't <code>bindgen</code> generating bindings to inline functions?&quot;</a></p>
<p>If not, consider filing an issue!</p>
<h3><a class="header" href="#why-isnt-bindgen-generating-bindings-to-inline-functions" id="why-isnt-bindgen-generating-bindings-to-inline-functions">Why isn't <code>bindgen</code> generating bindings to inline functions?</a></h3>
<p>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.</p>
<p>However, if you are compiling the C/C++ yourself (rather than using a system
shared library, for example), then you can pass <code>-fkeep-inline-functions</code> or
<code>-fno-inline-functions</code> to <code>gcc</code> or <code>clang</code>, and invoke <code>bindgen</code> with either
the <code>bindgen::Builder::generate_inline_functions</code> method or the
<code>--generate-inline-functions</code> flag.</p>
<p>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.</p>
<p>As an alternative, you can invoke <code>bindgen</code> with either the
<code>bindgen::Builder::wrap_static_fns</code> method or the <code>--wrap-static-fns</code> flag.
Which generates a C source file that can be compiled against the input headers
to produce Rust headers for <code>static</code> and <code>static inline</code> functions. See <a href="https://github.com/rust-lang/rust-bindgen/discussions/2405">How to
handle <code>static inline</code> functions</a>
for further information.</p>
<h3><a class="header" href="#does-bindgen-support-the-c-standard-template-library-stl" id="does-bindgen-support-the-c-standard-template-library-stl">Does <code>bindgen</code> support the C++ Standard Template Library (STL)?</a></h3>
<p>Sort of. A little. Depends what you mean by &quot;support&quot;.</p>
<p>Most functions, methods, constructors, and destructors are inline in the
STL. That ties our hands when it comes to linking: <a href="faq.html#why-isnt-bindgen-generating-bindings-to-inline-functions">&quot;Why isn't <code>bindgen</code> generating bindings to inline functions?&quot;</a></p>
<p>As far as generating opaque blobs of bytes with the correct size and alignment,
<code>bindgen</code> can do pretty well. This is typically enough to let you use types that
transitively contain STL things. We generally recommend marking <code>std::.*</code> as
opaque, and then allowlisting only the specific things you need from the library
you're binding to that is pulling in STL headers.</p>
<h3><a class="header" href="#how-to-deal-with-bindgen-generated-padding-fields" id="how-to-deal-with-bindgen-generated-padding-fields">How to deal with bindgen generated padding fields?</a></h3>
<p>Depending the architecture, toolchain versions and source struct, it is
possible that bindgen will generate padding fields named <code>__bindgen_padding_N</code>.
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 <code>Default</code> trait. You can either enable this when
constructing the <code>Builder</code> using the <code>derive_default</code> method, or you can
implement this per struct using:</p>
<pre><code class="language-rust ignore">impl Default for SRC_DATA {
fn default() -&gt; Self {
unsafe { std::mem::zeroed() }
}
}
</code></pre>
<p>This makes it possible to initialize <code>SRC_DATA</code> by:</p>
<pre><code class="language-rust ignore">SRC_DATA {
field_a: &quot;foo&quot;,
field_b: &quot;bar&quot;,
..Default::default()
}
</code></pre>
<p>In the case bindgen generates a padding field, then this field will
be automatically initialized by <code>..Default::default()</code>.</p>
<h3><a class="header" href="#how-to-generate-bindings-for-a-custom-target" id="how-to-generate-bindings-for-a-custom-target">How to generate bindings for a custom target?</a></h3>
<p>To generate bindings for a custom target you only need to pass the <code>--target</code>
argument to <code>libclang</code>. For example, if you want to generate bindings for the
<code>armv7a-none-eabi</code> target using the command line, you need to invoke <code>bindgen</code>
like so:</p>
<pre><code class="language-bash">$ bindgen &lt;input_headers&gt; -- --target=armv7a-none-eabi
</code></pre>
<p>If you are using <code>bindgen</code> as a library, you should call
<code>builder.clang_arg(&quot;--target=armv7a-none-eabi&quot;)</code> on your <code>builder</code>.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
<script type="text/javascript">
window.addEventListener('load', function() {
window.setTimeout(window.print, 100);
});
</script>
</body>
</html>