### Build Script Setup with autocxx-build Source: https://context7.com/google/autocxx/llms.txt Configure your `build.rs` file to process the `include_cpp!` macro and compile the generated C++ code. The builder takes your Rust source file path and C++ include directories. ```APIDOC ## Build Script Setup with autocxx-build ### Description Configure your `build.rs` to process the `include_cpp!` macro and compile the generated C++ code. The builder takes your Rust source file path and C++ include directories. ### Method Build Script Configuration ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```rust // build.rs fn main() -> miette::Result<()> { let include_path = std::path::PathBuf::from("src"); // Create builder with source file and include paths let mut b = autocxx_build::Builder::new("src/main.rs", &[&include_path]) .extra_clang_args(&["-std=c++17"]) // Optional: C++ standard version for parsing .build()?; // Configure C++ compilation b.flag_if_supported("-std=c++17") // Same C++ version for compilation .flag_if_supported("-Wall") .compile("my-autocxx-bindings"); // Arbitrary library name // Rebuild triggers println!("cargo:rerun-if-changed=src/main.rs"); println!("cargo:rerun-if-changed=src/input.h"); Ok(()) } ``` ### Response #### Success Response (200) N/A (Build script execution) #### Response Example N/A ``` -------------------------------- ### Mixing Manual and Autocxx Bindings (Referencing Autocxx from Manual) Source: https://github.com/google/autocxx/blob/main/book/src/workflow.md This example shows how to use manually crafted cxx::bridge modules that refer to types and functions generated by autocxx. This is useful for extending autocxx's capabilities by hand-crafting bindings for specific cases. ```rust autocxx::include_cpp! { #include "foo.h" safety!(unsafe_ffi) generate!("take_A") generate!("A") } #[cxx::bridge] mod ffi2 { unsafe extern "C++" { include!("foo.h"); type A = crate::ffi::A; fn give_A() -> UniquePtr; // in practice, autocxx could happily do this } } fn main() { let a = ffi2::give_A(); assert_eq!(ffi::take_A(&a), autocxx::c_int(5)); } ``` -------------------------------- ### Integrate C++ Class and Function with Autocxx Source: https://context7.com/google/autocxx/llms.txt This example demonstrates how to define a C++ class and function in a header file, configure the build script to compile them, and invoke them from Rust. It showcases the use of include_cpp! for binding generation and handling C++ objects within Rust. ```rust use autocxx::prelude::*;include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("DoMath") generate!("Goat") } fn main() { println!("C++ math: 4 * 3 = {}", ffi::DoMath(4)); let mut goat = ffi::Goat::new().within_box(); goat.as_mut().add_a_horn(); goat.as_mut().add_a_horn(); let description = goat.describe().as_ref().unwrap().to_string_lossy(); assert_eq!(description, "This goat has 2 horns."); println!("{}", description); } ``` ```cpp #pragma once #include #include #include class Goat { public: Goat() : horns(0) {} void add_a_horn() { horns++; } std::string describe() const { std::ostringstream oss; std::string plural = horns == 1 ? "" : "s"; oss << "This goat has " << horns << " horn" << plural << "."; return oss.str(); } private: uint32_t horns; }; inline uint32_t DoMath(uint32_t a) { return a * 3; } ``` ```rust fn main() -> miette::Result<()> { let path = std::path::PathBuf::from("src"); let mut b = autocxx_build::Builder::new("src/main.rs", [&path]).build()?; b.flag_if_supported("-std=c++14").compile("autocxx-demo"); println!("cargo:rerun-if-changed=src/main.rs"); println!("cargo:rerun-if-changed=src/input.h"); Ok(()) } ``` -------------------------------- ### Mixing Manual and Autocxx Bindings (Referencing Manual from Autocxx) Source: https://github.com/google/autocxx/blob/main/book/src/workflow.md This example demonstrates how autocxx can generate bindings while referring to types defined in a manual cxx::bridge module using `extern_cpp_opaque_type!`. This allows autocxx to work with types that are manually defined. ```rust autocxx::include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("handle_a") generate!("create_a") extern_cpp_opaque_type!("A", ffi2::A) } #[cxx::bridge] pub mod ffi2 { unsafe extern "C++" { include!("input.h"); type A; } impl UniquePtr {} } fn main() { let a = ffi::create_a(); ffi::handle_a(&a); } ``` -------------------------------- ### Object Construction in Rust via autocxx Source: https://github.com/google/autocxx/blob/main/book/src/cpp_types.md Details the methods for constructing C++ objects in Rust, distinguishing between POD and non-POD types and providing examples for heap and stack allocation. ```APIDOC ## Object Construction in Rust via autocxx ### Description This section details how to construct C++ objects within a Rust environment using `autocxx`, covering both POD and non-POD types, and illustrating various allocation strategies. ### Constructing POD Objects POD objects are constructed by calling their `new` associated function. Constructor overloading follows the same rules as other C++ functions. ### Constructing Non-POD Objects Non-POD object construction involves two steps: 1. Call the `new` associated function to obtain an object implementing `moveit::New`. 2. Use this object to create the actual C++ object on the heap or stack. #### Allocation Methods for Non-POD Objects: | Target Allocation | Method | Resulting Type | Example | | :---------------- | :------------------------------------------------------------------ | :-------------------- | :------------------------------------------------------------------------------------------------------------------------------------ | | C++ Heap | `Within.within_unique_ptr()` or `UniquePtr::emplace()` | `cxx::UniquePtr` | `let mut obj = ffi::Goldfish::new().within_unique_ptr()` or `let mut obj = UniquePtr::emplace(ffi::Goldfish::new())` | | Rust Heap | `Within.within_box()` or `Box::emplace()` | `Pin>` | `let mut obj = ffi::Goldfish::new().within_box()` or `let mut obj = Box::emplace(ffi::Goldfish::new())` | | Rust Stack | `moveit` macro | `&mut T` (effectively) | `moveit! { let mut obj = ffi::Goldfish::new() }` | *Note: For heap construction, the `emplace` and `.within_...` forms are functionally identical. Choose based on preference.* ``` -------------------------------- ### Implement Rust Subclasses with Default C++ Behavior Source: https://github.com/google/autocxx/blob/main/book/src/rust_calls.md Illustrates creating multiple Rust subclasses of a C++ base class, where some subclasses override methods and others inherit the default C++ implementation. This example uses a 'Dinosaur' class with an 'eat' method, showing how to selectively implement behavior in Rust subclasses. ```rust use autocxx::prelude::*; use autocxx::subclass::*; include_cpp! { #include "input.h" safety!(unsafe_ffi) subclass!("Dinosaur", TRex) subclass!("Dinosaur", Diplodocus) } use ffi::*; #[subclass] #[derive(Default)] pub struct TRex; #[subclass] #[derive(Default)] pub struct Diplodocus; impl Dinosaur_methods for TRex { // TRex does NOT implement the 'eat' method // so C++ behavior will be used } impl Dinosaur_methods for Diplodocus { fn eat(&self) { println!("Ahh, some nice juicy leaves."); // Could call self.eat_super() if we // developed unexpected carnivorous cravings. } } fn main() { let trex = TRex::default_rust_owned(); trex.borrow().as_ref().eat(); // eats human let diplo = Diplodocus::default_rust_owned(); diplo.borrow().as_ref().eat(); // eats shoots and leaves } ``` ```cpp #include class Dinosaur { public: Dinosaur() {} virtual void eat() const { std::cout << "Roarrr!! I ate you!\n"; } virtual ~Dinosaur() {} }; ``` -------------------------------- ### Generate Rust Bindings for C++ Function using autocxx Source: https://github.com/google/autocxx/blob/main/book/src/index.md This example demonstrates how to use autocxx to generate Rust bindings for a simple C++ function. It includes the necessary C++ code and the Rust code that utilizes the generated bindings to call the C++ function. The `include_cpp!` macro is used to define the C++ code and specify which functions to generate bindings for. ```rust autocxx_integration_tests::doctest( "", "#include inline uint32_t do_math(uint32_t a, uint32_t b) { return a+b; }", { // Use all the autocxx types which might be handy. use autocxx::prelude::*; include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("do_math") // allowlist a function } fn main() { assert_eq!(ffi::do_math(12, 13), 25); } } ) ``` -------------------------------- ### Rust Heap vs C++ Heap Allocation with autocxx Source: https://github.com/google/autocxx/blob/main/book/src/cpp_types.md Demonstrates creating C++ objects on the heap using `cxx::UniquePtr` and `Box` within Rust. `UniquePtr` allows `NULL` values and requires unwrapping, while `Box` guarantees non-nullability. Both methods allow interaction with C++ methods like `set` and `get`. ```rust autocxx_integration_tests::doctest("void A::set(uint32_t val) { a = val; }\nuint32_t A::get() const { return a; }", "#include \n#include \nstruct A {\n A() {}\n void set(uint32_t val);\n uint32_t get() const;\n uint32_t a;\n};\n", {\nuse autocxx::prelude::*;\n\ninclude_cpp! {\n #include \"input.h\"\n safety!(unsafe_ffi)\n generate!(\"A\")\n}\n\nfn main() {\n moveit! {\n let mut stack_obj = ffi::A::new();\n }\n stack_obj.as_mut().set(42);\n assert_eq!(stack_obj.get(), 42);\n\n let mut heap_obj = ffi::A::new().within_unique_ptr();\n heap_obj.pin_mut().set(42);\n assert_eq!(heap_obj.get(), 42);\n\n let mut another_heap_obj = ffi::A::new().within_box();\n another_heap_obj.as_mut().set(42);\n assert_eq!(another_heap_obj.get(), 42);\n}\n}) ``` -------------------------------- ### Generate Rust Bindings for C++ Class using autocxx Source: https://github.com/google/autocxx/blob/main/book/src/index.md This example shows how to generate Rust bindings for a C++ class, including its constructor, destructor, methods, and member variables. The `include_cpp!` macro is used to define the C++ class definition and implementation, and then specify the class to generate bindings for. The Rust code demonstrates creating an instance of the C++ class, calling its methods, and interacting with its state. ```rust autocxx_integration_tests::doctest( "\n#include \nvoid Goat::add_a_horn() { horns++; }\nGoat::Goat() : horns(0) {}\nGoat::~Goat() {} \nstd::string Goat::describe() const {\n std::ostringstream oss;\n std::string plural = horns == 1 ? \"\" : \"s\";\n oss << \"This goat has \" << horns << \" horn\" << plural << \".\";\n return oss.str();\n}\n", "#include \n#include \n\nclass Goat {\npublic:\n Goat();\n ~Goat();\n void add_a_horn();\n std::string describe() const;\nprivate:\n uint32_t horns;\n};\n", { use autocxx::prelude::*; include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("Goat") // allowlist a type and all its methods } fn main() { let mut goat = ffi::Goat::new().within_unique_ptr(); // returns a cxx::UniquePtr, i.e. a std::unique_ptr goat.pin_mut().add_a_horn(); goat.pin_mut().add_a_horn(); assert_eq!(goat.describe().as_ref().unwrap().to_string_lossy(), "This goat has 2 horns."); } } ) ``` -------------------------------- ### Rust: Get Reference to CxxString with Autocxx Source: https://github.com/google/autocxx/blob/main/book/src/primitives.md Demonstrates the use of cxx::let_cxx_string macro to obtain a reference to a CxxString in Rust, providing an alternative to UniquePtr when only a reference is needed. ```rust cxx::let_cxx_string ``` -------------------------------- ### Implementing Rust Subclasses for C++ Observer Patterns Source: https://github.com/google/autocxx/blob/main/book/src/rust_calls.md Demonstrates how to create Rust subclasses of C++ classes to implement observer patterns, allowing C++ to call back into Rust. ```APIDOC ## POST /api/users ### Description This endpoint allows users to create new user accounts. ### Method POST ### Endpoint /api/users ### Parameters #### Query Parameters - **username** (string) - Required - The desired username for the new account. - **email** (string) - Required - The email address for the new account. #### Request Body - **password** (string) - Required - The password for the new account. ### Request Example { "password": "securepassword123" } ### Response #### Success Response (200) - **userId** (string) - The unique identifier for the newly created user. - **message** (string) - A confirmation message. #### Response Example { "userId": "usr_123abc456", "message": "User account created successfully." } ``` -------------------------------- ### Implement build.rs for C++ Compilation Source: https://github.com/google/autocxx/blob/main/book/src/tutorial.md Create a build script to compile C++ code and generate bindings. This script defines the include path and specifies the target source file for the autocxx builder. ```rust fn main() -> miette::Result<()> { let include_path = std::path::PathBuf::from("src"); let mut b = autocxx_build::Builder::new("src/main.rs", &[&include_path]).build()?; b.flag_if_supported("-std=c++14") .compile("autocxx-demo"); println!("cargo:rerun-if-changed=src/main.rs"); Ok(()) } ``` -------------------------------- ### Creating Objects on the Stack with moveit! Source: https://context7.com/google/autocxx/llms.txt Use the `moveit!` macro to create non-POD C++ objects on the Rust stack, avoiding heap allocation while maintaining proper C++ semantics. ```APIDOC ## Creating Objects on the Stack with moveit! ### Description Use the `moveit!` macro to create non-POD C++ objects on the Rust stack, avoiding heap allocation while maintaining proper C++ semantics. ### Method Object Instantiation ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```rust use autocxx::prelude::*; include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("Widget") } fn main() { // Create object on the stack using moveit! macro moveit! { let mut stack_widget = ffi::Widget::new(); } // Use as_mut() to get mutable access stack_widget.as_mut().configure(42); // Use as_ref() for immutable access let value = stack_widget.as_ref().get_value(); // Pass to functions expecting references ffi::process_widget(&*stack_widget); } ``` ### Response #### Success Response (200) N/A (Object creation) #### Response Example N/A ``` -------------------------------- ### Handle RValue References and Move Parameters in autocxx Source: https://context7.com/google/autocxx/llms.txt Explains how autocxx manages C++ rvalue reference parameters, which signify move semantics and always consume the passed object. The examples demonstrate passing both heap-allocated and stack-allocated objects to functions expecting rvalue references, showing that these objects are consumed upon passing. ```rust use autocxx::prelude::*; include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("Buffer") generate!("transfer_buffer") // void transfer_buffer(Buffer&& b) } fn main() { // Heap-allocated object let heap_buffer = ffi::Buffer::new().within_unique_ptr(); ffi::transfer_buffer(heap_buffer); // Consumed via move // heap_buffer is no longer valid // Stack-allocated object moveit! { let stack_buffer = ffi::Buffer::new(); } ffi::transfer_buffer(stack_buffer); // Also consumed // stack_buffer is no longer valid } ``` -------------------------------- ### C++ Integer Integration Source: https://github.com/google/autocxx/blob/main/book/src/primitives.md Demonstrates how to use autocxx to bind C++ functions using platform-independent integer types. ```APIDOC ## C++ Integer Integration ### Description Allows binding C++ functions that utilize integer types with non-predictable bit sizes across architectures by using the `c_int` wrapper. ### Method N/A (Rust FFI binding) ### Endpoint `include_cpp!` macro block ### Parameters #### Request Body - **generate** (string) - Required - The name of the C++ function to expose to Rust. - **safety** (string) - Required - The safety policy (e.g., `unsafe_ffi`). ### Request Example ```rust include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("do_math") } ``` ### Response #### Success Response (200) - **ffi::do_math** (function) - A Rust-callable function accepting `c_int` arguments. ``` -------------------------------- ### Basic include_cpp macro usage Source: https://github.com/google/autocxx/blob/main/book/src/allowlist.md Demonstrates the fundamental syntax for including a C++ header and generating bindings for a specific function. This macro must be used within a Rust file to bridge the C++ interface. ```rust use autocxx::prelude::*; include_cpp! { #include "my_header.h" generate!("MyAPIFunction") } ``` -------------------------------- ### Implement Rust Subclass for C++ Observer Pattern Source: https://github.com/google/autocxx/blob/main/book/src/rust_calls.md Demonstrates how to create a Rust subclass of a C++ observer class using autocxx. This allows C++ to call Rust methods when events occur, such as a goat being fed. It includes setting up the C++ interface, defining the Rust subclass, and implementing the callback method. ```rust use autocxx::prelude::*; use autocxx::subclass::*; include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("register_observer") generate!("deregister_observer") generate!("feed_goat") subclass!("GoatObserver", MyGoatObserver) } use ffi::*; #[subclass] #[derive(Default)] pub struct MyGoatObserver; impl GoatObserver_methods for MyGoatObserver { fn goat_full(&self) { println!("BURP!"); } } impl Drop for MyGoatObserver { fn drop(&mut self) { deregister_observer(); } } fn main() { let goat_obs = MyGoatObserver::default_rust_owned(); // Register a reference to the superclass &ffi::GoatObserver register_observer(goat_obs.as_ref().borrow().as_ref()); feed_goat(); feed_goat(); feed_goat(); // prints BURP! } ``` ```cpp GoatObserver* obs = NULL; int goat_feed = 0; void register_observer(const GoatObserver& observer) { obs = const_cast(&observer); } void deregister_observer() { obs = NULL; }; void feed_goat() { goat_feed++; if (goat_feed > 2 && obs) { obs->goat_full(); } } class GoatObserver { public: virtual void goat_full() const = 0; virtual ~GoatObserver() {} }; void register_observer(const GoatObserver& observer); void deregister_observer(); void feed_goat(); ``` -------------------------------- ### Calling Superclass Methods from Rust Subclasses Source: https://github.com/google/autocxx/blob/main/book/src/rust_calls.md Illustrates how Rust subclasses can optionally implement superclass methods or rely on the default C++ implementation, and how to call superclass methods. ```APIDOC ## GET /api/users/{userId} ### Description Retrieves details for a specific user. ### Method GET ### Endpoint /api/users/{userId} ### Parameters #### Path Parameters - **userId** (string) - Required - The unique identifier of the user to retrieve. ### Response #### Success Response (200) - **userId** (string) - The unique identifier of the user. - **username** (string) - The username of the user. - **email** (string) - The email address of the user. #### Response Example { "userId": "usr_123abc456", "username": "johndoe", "email": "john.doe@example.com" } ``` -------------------------------- ### Configure Build Script for Autocxx Source: https://context7.com/google/autocxx/llms.txt The build.rs file uses autocxx-build to process headers and compile the generated C++ code. It requires specifying the source file and include directories. ```rust fn main() -> miette::Result<()> { let include_path = std::path::PathBuf::from("src"); let mut b = autocxx_build::Builder::new("src/main.rs", &[&include_path]) .extra_clang_args(&["-std=c++17"]) .build()?; b.flag_if_supported("-std=c++17") .flag_if_supported("-Wall") .compile("my-autocxx-bindings"); println!("cargo:rerun-if-changed=src/main.rs"); println!("cargo:rerun-if-changed=src/input.h"); Ok(())} ``` -------------------------------- ### Constructing non-POD C++ objects in Rust Source: https://github.com/google/autocxx/blob/main/book/src/cpp_types.md Demonstrates the three primary ways to construct non-POD C++ objects in Rust using autocxx and the moveit crate: C++ heap, Rust heap, and Rust stack. ```rust // C++ heap (UniquePtr) let mut obj = ffi::Goldfish::new().within_unique_ptr(); // or let mut obj = UniquePtr::emplace(ffi::Goldfish::new()); // Rust heap (Pin>) let mut obj = ffi::Goldfish::new().within_box(); // or let mut obj = Box::emplace(ffi::Goldfish::new()); // Rust stack moveit! { let mut obj = ffi::Goldfish::new() }; ``` -------------------------------- ### Include and invoke C++ code in Rust with Autocxx Source: https://github.com/google/autocxx/blob/main/README.md Demonstrates how to use the include_cpp macro to generate Rust bindings for a C++ header and invoke a C++ function. This requires the autocxx crate and proper build configuration to link the C++ source. ```rust autocxx::include_cpp! { #include "url/origin.h" generate!("url::Origin") safety!(unsafe_ffi) } fn main() { let o = ffi::url::Origin::CreateFromNormalizedTuple("https", "google.com", 443); let uri = o.Serialize(); println!("URI is {}", uri.to_str().unwrap()); } ``` -------------------------------- ### Run autocxx reduction in Chromium environment Source: https://github.com/google/autocxx/blob/main/tools/reduce/README.md Configures the environment with a specific CLANG_PATH to run the reduction tool within the context of a Chromium build. This involves setting the compiler path and executing the reduction against a target repro.json file. ```bash CLANG_PATH=~/chromium/src/third_party/llvm-build/Release+Asserts/bin/clang++ AUTOCXX_REPRO_CASE=repro.json autoninja -C out/Release chrome CLANG_PATH=~/chromium/src/third_party/llvm-build/Release+Asserts/bin/clang++ cargo run --release -- --problem $EXPECTED_COMPILE_ERROR -k --clang-arg=-std=c++17 --creduce-arg=--n --creduce-arg=192 repro -r ~/dev/chromium/src/out/Release/repro.json ``` -------------------------------- ### Implement C++ Observer Pattern with Rust Subclasses Source: https://context7.com/google/autocxx/llms.txt Demonstrates how to create a Rust struct that acts as a subclass for a C++ base class. It uses the #[subclass] attribute to implement virtual methods and manage lifecycle via Rust's drop trait. ```rust use autocxx::prelude::*; use autocxx::subclass::*; include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("register_observer") generate!("deregister_observer") generate!("trigger_event") subclass!("EventObserver", MyRustObserver) } #[subclass] #[derive(Default)] pub struct MyRustObserver { event_count: std::cell::Cell, } impl ffi::EventObserver_methods for MyRustObserver { fn on_event(&self, value: i32) { self.event_count.set(self.event_count.get() + 1); println!("Event received: {} (count: {})", value, self.event_count.get()); } } impl Drop for MyRustObserver { fn drop(&mut self) { ffi::deregister_observer(); } } fn main() { let observer = MyRustObserver::default_rust_owned(); ffi::register_observer(observer.as_ref().borrow().as_ref()); ffi::trigger_event(42); ffi::trigger_event(100); } ``` -------------------------------- ### Configure Cargo Dependencies for autocxx Source: https://github.com/google/autocxx/blob/main/book/src/tutorial.md Add the necessary dependencies to your Cargo.toml file to enable autocxx and cxx support, along with optional build-time error reporting tools. ```toml [dependencies] autocxx = "0.30.0" cxx = "1.0" [build-dependencies] autocxx-build = "0.30.0" miette = { version = "5", features = ["fancy"] } ``` -------------------------------- ### Subclass Ownership and Casting Source: https://github.com/google/autocxx/blob/main/book/src/rust_calls.md Explains the different ownership models for Rust subclasses (C++ owned, Rust owned, self-owned) and how to cast subclasses to their superclasses. ```APIDOC ## PUT /api/users/{userId} ### Description Updates an existing user's information. ### Method PUT ### Endpoint /api/users/{userId} ### Parameters #### Path Parameters - **userId** (string) - Required - The unique identifier of the user to update. #### Request Body - **email** (string) - Optional - The new email address for the user. - **username** (string) - Optional - The new username for the user. ### Request Example { "email": "john.doe.updated@example.com" } ### Response #### Success Response (200) - **message** (string) - A confirmation message indicating the user was updated. #### Response Example { "message": "User account updated successfully." } ``` -------------------------------- ### Calling C++ Functions with Value Parameters in Rust Source: https://github.com/google/autocxx/blob/main/book/src/cpp_functions.md Demonstrates how to call C++ functions that accept non-POD value parameters from Rust. It shows how to pass objects using Rust's `cxx::UniquePtr` or `&T`, allowing for either C++-like semantics (parameter is copied) or Rust-like semantics (parameter is consumed and destroyed). Supports passing types implementing `ValueParam`. ```rust use autocxx::prelude::*; include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("Goat") generate!("feed_goat") } fn main() { let goat = ffi::Goat::new().within_unique_ptr(); // returns a cxx::UniquePtr, i.e. a std::unique_ptr // C++-like semantics... ffi::feed_goat(&goat); // ... you've still got the goat! ffi::feed_goat(&goat); // Or, Rust-like semantics, where the goat is consumed. ffi::feed_goat(goat); // No goat any more... // ffi::feed_goat(&goat); // doesn't compile } ``` -------------------------------- ### Calling Const Methods Source: https://github.com/google/autocxx/blob/main/book/src/cpp_functions.md Demonstrates how to call a const method on a C++ object generated by autocxx. No special handling is required for const methods. ```APIDOC ## Calling Const Methods ### Description This section shows how to call a `const` method from a C++ class within Rust using `autocxx`. For `const` methods, direct calls are supported without additional pinning. ### Method N/A (Example demonstrates Rust code calling C++) ### Endpoint N/A (This is an integration test example, not a network endpoint) ### Parameters N/A ### Request Example ```rust use autocxx::prelude::* include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("Sloth") } fn main() { let sloth = ffi::Sloth::new().within_unique_ptr(); sloth.sleep(); // Calling a const method sloth.sleep(); // Calling it again } ``` ### Response N/A (This is a code execution example, not an API response) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Rust: Perform Math Operation with C++ Integers using Autocxx Source: https://github.com/google/autocxx/blob/main/book/src/primitives.md Demonstrates how to use autocxx to call a C++ function 'do_math' that takes and returns integers. It shows the use of c_int for type compatibility between Rust and C++ integer types. ```rust autocxx_integration_tests::doctest( "", "inline int do_math(int a, int b) { return a+b; }", { use autocxx::prelude::*; include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("do_math") } fn main() { assert_eq!(ffi::do_math(c_int(12), c_int(13)), c_int(25)); } } ) ``` -------------------------------- ### Access C++ Preprocessor Constants Source: https://context7.com/google/autocxx/llms.txt Demonstrates how to expose C++ #define constants to Rust. Numeric values are mapped directly, while string constants require conversion from null-terminated byte arrays. ```rust use autocxx::prelude::*; include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("MAX_SIZE") generate!("VERSION_STRING") } fn main() { let buffer_size = ffi::MAX_SIZE; let version = std::str::from_utf8(&ffi::VERSION_STRING) .unwrap() .trim_end_matches(char::from(0)); println!("Version: {}, Max size: {}", version, buffer_size); } ``` -------------------------------- ### Define Project Dependencies Source: https://context7.com/google/autocxx/llms.txt Required dependencies for an Autocxx project, including the main library and build-time tools. ```toml [package] name = "my-cpp-project" version = "0.1.0" edition = "2021" [dependencies] autocxx = "0.30.0" cxx = "1.0" [build-dependencies] autocxx-build = "0.30.0" miette = { version = "5", features = ["fancy"] } ``` -------------------------------- ### Export Rust Functions to C++ Source: https://context7.com/google/autocxx/llms.txt Shows how to expose Rust functions to C++ by using the extern_rust_function attribute, enabling C++ code to trigger callbacks or invoke logic defined in Rust. ```rust use autocxx::prelude::*;use autocxx::extern_rust::extern_rust_function;include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("trigger_callback") } #[extern_rust_function] pub fn rust_callback(value: i32) -> i32 { println!("Rust callback received: {}", value); value * 2 } fn main() { ffi::trigger_callback(); } ``` -------------------------------- ### Run autocxx engine tests with logging Source: https://github.com/google/autocxx/blob/main/book/src/contributing.md Executes the autocxx test suite with backtrace enabled and logging set to info level. This is useful for debugging conversion issues in the engine by capturing output that is otherwise swallowed by cargo build scripts. ```shell RUST_BACKTRACE=1 RUST_LOG=autocxx_engine=info cargo test --all test_cycle_string_full_pipeline -- --nocapture ``` -------------------------------- ### C++ String Handling Source: https://github.com/google/autocxx/blob/main/book/src/primitives.md Explains how autocxx handles std::string conversions between Rust and C++. ```APIDOC ## C++ String Handling ### Description Details the automatic conversion of Rust strings to C++ `std::string` objects using the `ffi::ToCppString` trait. ### Method N/A (Rust FFI binding) ### Endpoint `ffi::ToCppString` trait implementation ### Parameters #### Request Body - **input** (string/UniquePtr) - Required - The string data to be passed to the C++ function. ### Request Example ```rust // Rust string is automatically converted to std::string assert_eq!(ffi::take_string("hello"), 5); ``` ### Response #### Success Response (200) - **make_string** (function) - Returns a `UniquePtr` for manual C++ string management. ``` -------------------------------- ### Allocate C++ Objects on the Stack Source: https://context7.com/google/autocxx/llms.txt The moveit! macro allows for stack allocation of non-POD C++ objects in Rust, ensuring correct C++ lifecycle management. ```rust use autocxx::prelude::*;include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("Widget")}fn main() { moveit! { let mut stack_widget = ffi::Widget::new(); } stack_widget.as_mut().configure(42); let value = stack_widget.as_ref().get_value(); ffi::process_widget(&*stack_widget);} ``` -------------------------------- ### Generate POD Types with autocxx Source: https://context7.com/google/autocxx/llms.txt Demonstrates how to use `generate_pod!` to mark C++ structs as Plain-Old-Data (POD) types in Rust. This allows for direct field access and simpler handling as regular Rust types, avoiding the need for `within_unique_ptr` in many cases. It also shows how to generate functions that operate on these POD types. ```rust use autocxx::prelude::*; include_cpp! { #include "input.h" safety!(unsafe_ffi) generate_pod!("Point") // Mark as POD type generate!("calculate_distance") } // C++ header: // struct Point { // int32_t x; // int32_t y; // }; // double calculate_distance(Point a, Point b); fn main() { // POD types can be created directly - no within_unique_ptr needed let p1 = ffi::Point { x: 0, y: 0 }; let p2 = ffi::Point { x: 3, y: 4 }; // Direct field access println!("Point: ({}, {})", p1.x, p1.y); // Can be passed by value, stored in Vec, etc. let points: Vec = vec![p1, p2]; // Pass to C++ functions let distance = ffi::calculate_distance(points[0], points[1]); } ``` -------------------------------- ### Configure autocxx build with C++17 support Source: https://github.com/google/autocxx/blob/main/book/src/building.md This Rust snippet demonstrates how to configure the autocxx builder to include specific C++ standard flags. It ensures both the internal bindgen process and the final C++ compilation use the C++17 standard. ```rust fn main() { let path = std::path::PathBuf::from("src"); // include path let mut b = autocxx_build::Builder::new("src/main.rs", &[&path]) .extra_clang_args(&["-std=c++17"]) .build() .unwrap(); b.flag_if_supported("-std=c++17") // use "-std:c++17" here if using msvc on windows .compile("autocxx-demo"); // arbitrary library name, pick anything println!("cargo:rerun-if-changed=src/main.rs"); } ``` -------------------------------- ### Generate Bindings with include_cpp Source: https://github.com/google/autocxx/blob/main/book/src/tutorial.md Use the include_cpp macro in your Rust source code to specify the C++ header files and the functions or types you wish to expose to Rust. ```rust use autocxx::prelude::*; include_cpp! { #include "my_header.h" safety!(unsafe) generate!("DeepThought") } ``` -------------------------------- ### Passing Objects by Value and Reference in autocxx Source: https://context7.com/google/autocxx/llms.txt Illustrates how autocxx handles passing objects to C++ functions, supporting both Rust-style consumption (transferring ownership) and C++-style copying (keeping ownership). It covers passing by reference, passing by value, and using explicit copy/move semantics with `as_copy` and `as_mov` for stack-allocated objects. ```rust use autocxx::prelude::*; include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("Resource") generate!("consume_resource") // void consume_resource(Resource r) generate!("borrow_resource") // void borrow_resource(const Resource& r) } fn main() { let resource1 = ffi::Resource::new().within_unique_ptr(); let resource2 = ffi::Resource::new().within_unique_ptr(); let resource3 = ffi::Resource::new().within_unique_ptr(); // Pass by reference (C++ semantics) - keeps ownership ffi::consume_resource(&resource1); // Copies the resource ffi::consume_resource(&resource1); // Can use again // Pass by value (Rust semantics) - transfers ownership ffi::consume_resource(resource2); // Moves/consumes the resource // ffi::consume_resource(resource2); // ERROR: resource2 is moved // Const reference parameter ffi::borrow_resource(&resource3); // Just borrows // Stack-allocated objects with explicit move semantics moveit! { let mut stack_res = ffi::Resource::new(); } ffi::consume_resource(&*stack_res); // Copy ffi::consume_resource(as_copy(stack_res.as_ref())); // Explicit copy ffi::consume_resource(as_mov(stack_res)); // Move (consumes) } ``` -------------------------------- ### Calling Non-Const Methods Source: https://github.com/google/autocxx/blob/main/book/src/cpp_functions.md Demonstrates how to call a non-const method on a C++ object. This requires pinning the object using `.pin_mut()` before each method call. ```APIDOC ## Calling Non-Const Methods ### Description This section illustrates how to call a non-`const` method from a C++ class within Rust using `autocxx`. Due to Rust's memory safety rules, mutable references to C++ objects must be pinned. This is achieved by calling `.pin_mut()` on the `UniquePtr` before invoking the non-`const` method. ### Method N/A (Example demonstrates Rust code calling C++) ### Endpoint N/A (This is an integration test example, not a network endpoint) ### Parameters N/A ### Request Example ```rust use autocxx::prelude::* include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("Sloth") } fn main() { let mut sloth = ffi::Sloth::new().within_unique_ptr(); sloth.pin_mut().unpeel_from_tree(); // Calling a non-const method after pinning sloth.pin_mut().unpeel_from_tree(); // Calling it again after pinning } ``` ### Response N/A (This is a code execution example, not an API response) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Define Concrete Template Instantiations Source: https://context7.com/google/autocxx/llms.txt Shows how to create named Rust type aliases for specific C++ template instantiations using the concrete! directive, making complex types easier to manage. ```rust use autocxx::prelude::*;include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("prepare_tea") generate!("drink_tea") concrete!("Tea", BobaTea) concrete!("std::vector", IntVector) } fn main() { let tea: cxx::UniquePtr = ffi::prepare_tea(); ffi::drink_tea(&tea); } ``` -------------------------------- ### C++ Type Allowlisting and Binding Generation Source: https://github.com/google/autocxx/blob/main/book/src/cpp_types.md Explains how adding C++ types to the allowlist in autocxx generates Rust bindings, including methods. Types not on the allowlist may still be generated if required by other functions, but their methods will not be. ```APIDOC ## C++ Type Allowlisting and Binding Generation ### Description If you add a C++ struct, class, or enum to the [allowlist](allowlist.md), Rust bindings will be generated for that type and all its methods. If a type is not on the allowlist but is required by another function, bindings will still be generated for the type itself, but not for its methods. ### Key Differences: Rust vs. C++ Memory Management - **Rust**: The compiler can freely move data (memcpy). Objects are unaware of these moves. - **C++**: Objects remain in place until their move constructor is invoked. This allows for self-referential pointers, which can be invalidated by Rust's memcpy operations. ### POD vs. Non-POD Types **POD (Plain Old Data) Types**: - Trivial destructor and move constructor. - Rust can freely move these types. - Benefits: Usable as regular Rust types, direct field access, simpler handling. **Non-POD Types**: - Have non-trivial destructors or move constructors. - Rust cannot freely move these types. - Handling: Typically held in `cxx::UniquePtr`. Field access and mutable references (`&mut`) are restricted due to potential memory invalidation issues. `Pin<&mut>` references are possible but more complex. By default, `autocxx` generates non-POD types. Use `#[generate_pod]` to request POD generation. Build failures will occur if a C++ type does not meet POD requirements, unless overridden with the `IsRelocatable` C++ trait. ``` -------------------------------- ### Generate Bindings for Namespaced Functions in Rust Source: https://github.com/google/autocxx/blob/main/book/src/naming.md Demonstrates how autocxx generates Rust bindings for C++ functions residing in different namespaces. It showcases the use of `generate!` macro to include specific functions and their subsequent invocation in Rust. ```rust autocxx_integration_tests::doctest( "\nvoid generations::hey_boomer() {} void submarines::hey_boomer() {}", "\nnamespace generations {\n void hey_boomer();\n}\nnamespace submarines {\n void hey_boomer();\n}\n", { use autocxx::prelude::*; include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("submarines::hey_boomer") generate!("generations::hey_boomer") } fn main() { ffi::generations::hey_boomer(); // insults your elders and betters ffi::submarines::hey_boomer(); // launches missiles } } ) ``` -------------------------------- ### Linking Autocxx Bindings Across Modules Source: https://github.com/google/autocxx/blob/main/book/src/large_codebase.md Demonstrates how to define base and dependent modules in Rust using autocxx. It uses extern_cpp_type! to allow the dependent module to recognize types defined in the base module. ```rust use autocxx::prelude::*; pub mod base { autocxx::include_cpp! { #include "input.h" name!(ffi2) safety!(unsafe_ffi) generate!("A") generate!("B") } pub use ffi2::*; } pub mod dependent { autocxx::include_cpp! { #include "input.h" safety!(unsafe_ffi) generate!("handle_a") generate!("create_a") extern_cpp_type!("A", crate::base::A) extern_cpp_type!("B", super::super::base::B) pod!("B") } pub use ffi::*; } fn main() { let a = dependent::create_a(base::B::VARIANT).within_unique_ptr(); dependent::handle_a(&a); } ```