Fix null reference creation in shared_ptr::from_ptr_and_deleter. `shared_ptr::from_ptr_and_deleter` documents that `ptr` may be null (matching C++ `std::shared_ptr<T>(nullptr, deleter)`), but it built the result with `project_unchecked(delete_on_drop, |d| &*d.ptr)`, which creates a `&T` from `ptr`. For a null `ptr`, that is undefined behavior; in debug builds rustc's null-pointer check panics there. Instead, take the control block from the `DeleteOnDrop` allocation with `into_raw_parts` and pair it with `ptr` via `from_raw_parts`, without ever forming a reference. A null `ptr` still gets a control block (`use_count() == 1`) and the deleter is still called with null exactly once, as in C++. Adds tests for both the non-null and null cases; the null test panicked at the old `&*d.ptr` before this change. PiperOrigin-RevId: 999765860
Crubit is a bidirectional bindings generator for C++ and Rust, with the goal of integrating the C++ and Rust ecosystems.
See the status page for an overview of the current supported features.
{{#tab name=“Calling Rust from C++”}}
Consider the following Rust library:
pub struct Account { pub id: u64, pub balance: f64, } impl std::fmt::Display for Account { ... } // Takes shared references, mapped to const references in C++. pub fn calculate_interest(account: &Account, rate: f64) -> f64 { ... } // Takes a string slice, mapped to rs_std::StrRef in C++. pub fn is_valid_username(username: &str) -> bool { ... }
You can call these Rust functions from C++:
#include "path/to/account.h" #include <iostream> void demo() { account::Account my_account{.id = 123, .balance = 1000.0}; double interest = account::calculate_interest(my_account, 0.05); // my_account is printable because Account implements Display in Rust! std::cout << my_account << std::endl; if (account::is_valid_username("bob")) { std::cout << "Valid user" << std::endl; } }
{{#tab name=“Calling C++ from Rust”}}
Consider the following C++ header:
#include <string_view> #include <optional> #include <memory> struct User { int id; double balance; }; std::optional<User> FindUser(int id); std::unique_ptr<User> CreateUser(std::string_view name, int id);
You can call these C++ functions from Rust:
use cpp_std::unique_ptr; use ffi_11::c_int; use user_api::{CreateUser, FindUser, User}; let id: c_int = 123; let user: Option<User> = FindUser(id); if let Some(u) = user { let balance: f64 = u.balance; println!("User {} has balance {}", u.id, balance); } let new_user: unique_ptr<User> = CreateUser("Alice".into(), 456);
We have detailed walkthroughs on how to use C++ from Rust, or Rust from C++, using Crubit, as well as copy-pastable example code. The example code also includes spanshots of what the generated bindings look like.
examples/rust/examples/cpp/| Nightly | Stable |
|---|---|