If you're here, you want to call some C++ from Rust, right?
Let's assume you're calling into some existing C++ code.
You will need:
.h
files)#include "foo/bar.h"
and so your include path would need to include the directory containing the foo
directory).autocxx
helps with, but one solution is to emit a print from your build script.The rest of this 'getting started' section assumes Cargo - if you're using something else, see the building section.
First, add autocxx
and cxx
to your dependencies
and autocxx-build
to your build-dependencies
in your Cargo.toml
.
[dependencies] autocxx = "0.22.0" cxx = "1.0" [build-dependencies] autocxx-build = "0.22.0" miette = { version="4.3", features=["fancy"] } # optional but gives nicer error messages!
Now, add a build.rs
next to your Cargo.toml
(this is a standard cargo
build script). This is where you need your include path:
fn main() -> miette::Result<()> { let path = std::path::PathBuf::from("src"); // include path let mut b = autocxx_build::Builder::new("src/main.rs", &[&path]).build()?; // This assumes all your C++ bindings are in main.rs b.flag_if_supported("-std=c++14") .compile("autocxx-demo"); // arbitrary library name, pick anything println!("cargo:rerun-if-changed=src/main.rs"); // Add instructions to link to any C++ libraries you need. Ok(()) }
See the standard cargo build script output mechanisms for how you can direct Rust to link against pre-existing libraries, and see the building section of this book for more details about build options - for example, enabling C++17.
Finally, in your main.rs
you can use the include_cpp
macro which is the heart of autocxx
:
use autocxx::prelude::*; // use all the main autocxx functions include_cpp! { #include "my_header.h" // your header file name safety!(unsafe) // see details of unsafety policies described in the 'safety' section of the book generate!("DeepThought") // add this line for each function or type you wish to generate }
You should then find you can call the function by referring to an ffi
namespace:
fn main() { println!("The answer to Life, The Universe and Everything is {}", ffi::DeepThought()); }
C++ types such as std::string
and std::unique_ptr
are represented using the types provided by the marvellous cxx library. This provides good ergonomics and safety norms, so unlike with normal bindgen
bindings, you won't normally need to write unsafe
code for every function call.
Next, read the section about workflows.