Top Related Projects
Automatically generates Rust FFI bindings to C (and some C++) libraries.
Safe interop between Rust and C++
A project for generating C bindings from Rust code
Use C++ libraries from Rust
Quick Overview
cbindgen
is a tool that generates C bindings from Rust code. It is used to create C-compatible header files and source files from Rust code, allowing Rust libraries to be used in C and C++ projects.
Pros
- Automated Bindings Generation:
cbindgen
simplifies the process of creating C bindings for Rust code, reducing the manual effort required. - Cross-Language Interoperability: It enables Rust libraries to be used in C and C++ projects, improving the integration between these languages.
- Customizable Output:
cbindgen
provides various configuration options to customize the generated bindings, such as controlling the naming conventions and including/excluding specific types. - Rust-Friendly: The tool is developed and maintained by the Mozilla team, ensuring it aligns with Rust's best practices and evolves alongside the language.
Cons
- Limited Rust Feature Support: While
cbindgen
supports a wide range of Rust features, some more advanced or niche features may not be fully supported or may require additional configuration. - Potential for Complexity: Generating bindings for large or complex Rust codebases can result in complex C header files, which may require additional manual adjustments or understanding.
- Dependency Management: Using
cbindgen
-generated bindings in a C/C++ project may introduce additional dependency management challenges, as the Rust library and its dependencies need to be properly integrated. - Learning Curve: Developers new to the Rust ecosystem may need to invest time in understanding the tool's usage and configuration options to effectively integrate it into their projects.
Code Examples
Here are a few examples of how to use cbindgen
to generate C bindings from Rust code:
- Basic Usage:
// lib.rs
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
cbindgen --config cbindgen.toml --crate lib --output include/lib.h
This command generates a C header file lib.h
containing the bindings for the add
function.
- Customizing Output:
# cbindgen.toml
language = "C"
include_guard = "LIB_H"
cbindgen --config cbindgen.toml --crate lib --output include/lib.h
The configuration file cbindgen.toml
specifies the output language as C and sets an include guard for the generated header file.
- Handling Enums:
// lib.rs
pub enum Color {
Red,
Green,
Blue,
}
pub fn get_color_name(color: Color) -> &'static str {
match color {
Color::Red => "Red",
Color::Green => "Green",
Color::Blue => "Blue",
}
}
cbindgen --config cbindgen.toml --crate lib --output include/lib.h
The generated header file will include the Color
enum and the get_color_name
function that operates on it.
Getting Started
To use cbindgen
, follow these steps:
- Install
cbindgen
using Cargo:
cargo install cbindgen
- Create a Rust library project and add the necessary code:
cargo new --lib my-lib
-
Configure
cbindgen
by creating acbindgen.toml
file in the project's root directory. Customize the settings as needed. -
Generate the C bindings:
cbindgen --config cbindgen.toml --crate my-lib --output include/my-lib.h
- Include the generated header file in your C/C++ project and link against the Rust library.
Refer to the cbindgen documentation for more detailed information on configuration options and advanced usage.
Competitor Comparisons
Automatically generates Rust FFI bindings to C (and some C++) libraries.
Pros of rust-bindgen
- Supports generating bindings for multiple languages (C, C++, Rust)
- More mature project with a larger community and more frequent updates
- Offers more advanced features like custom derives and blacklisting
Cons of rust-bindgen
- Can be more complex to set up and configure
- May generate less idiomatic Rust code in some cases
- Slower compilation times due to its more comprehensive approach
Code Comparison
rust-bindgen:
let bindings = bindgen::Builder::default()
.header("wrapper.h")
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.generate()
.expect("Unable to generate bindings");
cbindgen:
cbindgen::Builder::new()
.with_crate(crate_dir)
.generate()
.expect("Unable to generate bindings")
.write_to_file("bindings.h");
Both tools aim to generate bindings between Rust and C/C++, but they approach the task differently. rust-bindgen focuses on generating Rust bindings from C/C++ headers, while cbindgen generates C/C++ headers from Rust code. rust-bindgen offers more flexibility and features, making it suitable for complex projects with diverse requirements. However, cbindgen excels in simplicity and generating idiomatic C/C++ headers from Rust code, making it a good choice for Rust-centric projects that need to expose APIs to C/C++.
Safe interop between Rust and C++
Pros of cxx
- Provides a more seamless integration between Rust and C++ with bidirectional FFI
- Offers automatic generation of safe bindings for both Rust and C++
- Includes runtime support for sharing common data types between languages
Cons of cxx
- Requires more setup and configuration compared to cbindgen
- Limited to C++11 and newer, potentially excluding older codebases
- May have a steeper learning curve for developers new to FFI
Code Comparison
cxx:
#[cxx::bridge]
mod ffi {
extern "Rust" {
fn process_data(input: &str) -> String;
}
extern "C++" {
include!("example.h");
fn call_cpp_function(arg: i32) -> i32;
}
}
cbindgen:
#[no_mangle]
pub extern "C" fn process_data(input: *const c_char) -> *mut c_char {
// Implementation
}
Summary
cxx offers a more comprehensive and bidirectional FFI solution, while cbindgen focuses on generating C bindings for Rust code. cxx provides better type safety and seamless integration but may be more complex to set up. cbindgen is simpler and more flexible but requires manual implementation of FFI functions on the C++ side.
A project for generating C bindings from Rust code
Pros of cbindgen
- Well-established and actively maintained project
- Extensive documentation and community support
- Widely used in Mozilla projects and other large-scale applications
Cons of cbindgen
- May have more features than necessary for smaller projects
- Learning curve can be steeper due to its comprehensive nature
- Potential performance overhead for very simple bindings
Code Comparison
This comparison is not applicable as both repositories refer to the same project. cbindgen is a single repository, and there isn't a separate mozilla/cbindgen> repository to compare it against.
Additional Notes
cbindgen is a tool for generating C bindings for Rust code. It's primarily used by Mozilla in projects like Firefox but has found adoption in various other projects requiring Rust-to-C interoperability. The tool automatically generates C/C++ header files from Rust source code, making it easier to use Rust libraries in C/C++ projects.
Key features include:
- Support for complex Rust types
- Customizable output through a configuration file
- Integration with Cargo build scripts
While cbindgen is powerful and feature-rich, smaller projects might find it overly complex for their needs. However, its widespread use and active development make it a reliable choice for many scenarios requiring Rust-to-C bindings.
Use C++ libraries from Rust
Pros of ritual
- Supports generating Rust bindings for C++ libraries, not just C
- Provides a more comprehensive binding generation solution, including build system integration
- Offers more customization options for generated bindings
Cons of ritual
- More complex setup and configuration required
- Less mature and less widely used compared to cbindgen
- May have more overhead for simpler binding generation tasks
Code comparison
cbindgen example:
#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
a + b
}
ritual example:
#[cxx::bridge]
mod ffi {
extern "Rust" {
fn add(a: i32, b: i32) -> i32;
}
}
fn add(a: i32, b: i32) -> i32 {
a + b
}
Summary
ritual offers more comprehensive C++ binding generation capabilities and customization options, but comes with increased complexity. cbindgen is simpler and more widely used for C bindings, making it a better choice for straightforward projects. The code examples demonstrate the different approaches: cbindgen uses a simple #[no_mangle]
attribute, while ritual employs a more structured cxx::bridge
module for defining the FFI boundary.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
cbindgen
cbindgen creates C/C++11 headers for Rust libraries which expose a public C API.
While you could do this by hand, it's not a particularly good use of your time. It's also much more likely to be error-prone than machine-generated headers that are based on your actual Rust code. The cbindgen developers have also worked closely with the developers of Rust to ensure that the headers we generate reflect actual guarantees about Rust's type layout and ABI.
C++ headers are nice because we can use operator overloads, constructors, enum classes, and templates to make the API more ergonomic and Rust-like. C headers are nice because you can be more confident that whoever you're interoperating with can handle them. With cbindgen you don't need to choose! You can just tell it to emit both from the same Rust library.
There are two ways to use cbindgen: as a standalone program, or as a library (presumably in your build.rs). There isn't really much practical difference, because cbindgen is a simple rust library with no interesting dependencies.
Using it as a program means people building your software will need it installed. Using it in your library means people may have to build cbindgen more frequently (e.g. every time they update their rust compiler).
It's worth noting that the development of cbindgen has been largely adhoc, as features have been added to support the usecases of the maintainers. This means cbindgen may randomly fail to support some particular situation simply because no one has put in the effort to handle it yet. Please file an issue if you run into such a situation. Although since we all have other jobs, you might need to do the implementation work too :)
Quick Start
To install cbindgen, you just need to run
cargo install --force cbindgen
(--force just makes it update to the latest cbindgen if it's already installed)
Or with Homebrew, run
brew install cbindgen
To use cbindgen you need two things:
- A configuration (cbindgen.toml, which can be empty to start)
- A Rust crate with a public C API
Then all you need to do is run it:
cbindgen --config cbindgen.toml --crate my_rust_library --output my_header.h
This produces a header file for C++. For C, add the --lang c
switch.
See cbindgen --help
for more options.
Get a template cbindgen.toml here.
Examples
We don't currently have a nice tailored example application, but the tests contain plenty of interesting examples of our features.
You may also find it interesting to browse the projects that are using cbindgen in production:
If you're using cbindgen
and would like to be added to this list, please open
a pull request!
Releases
cbindgen doesn't have a fixed release calendar, please file an issue requesting
a release if there's something fixed in trunk that you need released. Ping
@emilio
for increased effect.
Top Related Projects
Automatically generates Rust FFI bindings to C (and some C++) libraries.
Safe interop between Rust and C++
A project for generating C bindings from Rust code
Use C++ libraries from Rust
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot