githubcrates-iodocs-rs

CXX — safe interop between Rust and C++

This library provides a safe mechanism for calling C++ code from Rust and Rust code from C++. It carves out a regime of commonality where Rust and C++ are semantically very similar and guides the programmer to express their language boundary effectively within this regime. CXX fills in the low level stuff so that you get a safe binding, preventing the pitfalls of doing a foreign function interface over unsafe C-style signatures.

From a high level description of the language boundary, CXX uses static analysis of the types and function signatures to protect both Rust's and C++'s invariants. Then it uses a pair of code generators to implement the boundary efficiently on both sides together with any necessary static assertions for later in the build process to verify correctness.

The resulting FFI bridge operates at zero or negligible overhead, i.e. no copying, no serialization, no memory allocation, no runtime checks needed.

The FFI signatures are able to use native data structures from whichever side they please. In addition, CXX provides builtin bindings for key standard library types like strings, vectors, Box, unique_ptr, etc to expose an idiomatic API on those types to the other language.

Example

In this example we are writing a Rust application that calls a C++ client of a large-file blobstore service. The blobstore supports a put operation for a discontiguous buffer upload. For example we might be uploading snapshots of a circular buffer which would tend to consist of 2 pieces, or fragments of a file spread across memory for some other reason (like a rope data structure).

#[cxx::bridge]
mod ffi {
    extern "Rust" {
        type MultiBuf;

        fn next_chunk(buf: &mut MultiBuf) -> &[u8];
    }

    unsafe extern "C++" {
        include!("example/include/blobstore.h");

        type BlobstoreClient;

        fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;
        fn put(self: &BlobstoreClient, buf: &mut MultiBuf) -> Result<u64>;
    }
}

Now we simply provide Rust definitions of all the things in the extern "Rust" block and C++ definitions of all the things in the extern "C++" block, and get to call back and forth safely.

The Tutorial chapter walks through a fleshed out version of this blobstore example in full detail, including all of the Rust code and all of the C++ code. The code is also provided in runnable form in the demo directory of https://github.com/dtolnay/cxx. To try it out, run cargo run from that directory.

The key takeaway, which is enabled by the CXX library, is that the Rust code in main.rs is 100% ordinary safe Rust code working idiomatically with Rust types while the C++ code in blobstore.cc is 100% ordinary C++ code working idiomatically with C++ types. The Rust code feels like Rust and the C++ code feels like C++, not like C-style "FFI glue".


Chapter outline: See the hamburger menu in the top left if you are on a small screen and it didn't open with a sidebar by default.