# Inline C++

Crubit allows Rust code to call C++ libraries directly through generated
bindings. However, some C++ interfaces cannot yet be automatically bound by
Crubit, such as function templates and preprocessor macros.

Crubit provides two macros, `inline_cpp!` and `global_cpp!`, that allow you to
embed C++ declarations and expressions directly inside your Rust source files.
This lets you call unsupported C++ code without having to write separate C++
wrapper libraries.

## How to use Embedded C++ {#introduction}

Embedded C++ uses two macros depending on scope:

*   **`global_cpp!`**: Used at module scope (outside functions) to declare C++
    `#include` headers, structs, namespaces, and helper functions.
*   **`inline_cpp!`**: Used inside Rust functions to define and call an inline
    C++ expression.

You can use embedded C++ in two ways:

1.  **In a `rust_api_from_cpp` target (Recommended)**: When extending the
    generated Rust bindings of an existing C++ library using custom Rust source
    files (`additional_rust_srcs_for_crubit_bindings`).
2.  **In a `rust_library_with_embedded_cpp` or `rust_test_with_embedded_cpp`
    target**: When authoring a standalone Rust library or test with embedded C++
    without an underlying `cc_library`.

### 1. Using embedded C++ in a `rust_api_from_cpp` target {#rust_api_from_cpp}

If you maintain a `cc_library` and want to provide hand-written Rust helper
methods or trait implementations alongside your generated Crubit API, you can
pass custom Rust source files directly to `rust_api_from_cpp` via `srcs`.

Given a C++ header containing a template method that cannot be natively bound by
Crubit:

```cpp
// widget.h
namespace widget {
class Widget {
 public:
  template <typename T = void>
  static std::unique_ptr<Widget> Create(absl::string_view name);
 private:
  Widget(absl::string_view name);
};
}  // namespace widget
```

You can define the `BUILD` targets as follows:

```python
load(
    "//bazel:rust_api_from_cpp.bzl",
    "rust_api_from_cpp",
)

cc_library(
    name = "widget",
    hdrs = ["widget.h"],
    srcs = ["widget.cc"],
    aspect_hints = [":widget_rust.hint"],
    deps = [
        "@abseil-cpp//absl/strings",
    ],
)

rust_api_from_cpp(
    name = "widget_rust",
    cpp_target = ":widget",
    root_namespaces = ["widget"],
    srcs = ["widget_custom.rs"],
)
```

Inside `widget_custom.rs`, you can use `inline_cpp!` to bridge the C++ template
factory method directly into the crate's public API:

```rust
// widget_custom.rs (compiled directly into the widget_rust crate)
use inline_cpp_macro::inline_cpp;

impl Widget {
    /// Ergonomic Rust wrapper over a C++ factory function template.
    pub fn new_with_name(name: &str) -> cpp_std::unique_ptr<Widget> {
        let make_widget = inline_cpp! {
            (rs::StrRef name) -> std::unique_ptr<widget::Widget> {
                return widget::Widget::Create(name.to_string_view());
            }
        };
        make_widget(name)
    }
}
```

### 2. Using embedded C++ in a standalone `rust_library` or `rust_test` target {#build}

To write a standalone Rust library or test that uses embedded C++ without an
underlying `cc_library`, define your target with
`rust_library_with_embedded_cpp` or `rust_test_with_embedded_cpp`:

```live-snippet
cs/file:examples/cpp/inline_cpp/BUILD symbol:greeting_lib
```

The `deps_of_cc_library` attribute lists the C++ libraries that provide the
headers and symbols used in your embedded C++ snippets. For a complete runnable
example, see
[examples/cpp/inline_cpp/](https://github.com/google/crubit/tree/main/examples/cpp/inline_cpp/).

## Writing Embedded C++ {#writing_code}

### Declaring Headers with `global_cpp!` {#global_cpp}

Use `global_cpp!` at module scope (outside functions, including within nested
submodules) to specify `#include` headers and define supporting C++ types:

```live-snippet
cs/file:examples/cpp/inline_cpp/headers.rs content:^\s*global_cpp!\s*\{[\s\S]*?^\}
```

> **NOTE:** All `global_cpp!` declarations across a crate (including those
> inside nested submodules) are combined into a single C++ companion header. Any
> `inline_cpp!` block in the crate can access types declared in `global_cpp!`,
> regardless of which Rust module defined them. Standard Rust visibility (`pub`,
> `pub(crate)`) governs access to the wrapping Rust functions.

### Calling C++ with `inline_cpp!` {#inline_cpp}

Inside a Rust function, `inline_cpp!` defines an inline C++ expression. The
syntax requires a C++ parameter list, a return type arrow `->`, and the C++
function body.

For example, calling a C++ standard library math function:

```live-snippet
cs/file:examples/cpp/inline_cpp/math.rs function:compute_hypotenuse
```

Or calling an Abseil string utility:

```live-snippet
cs/file:examples/cpp/inline_cpp/greeting.rs function:format_greeting
```

`inline_cpp!` produces a callable Rust closure. The parameter and return types
of the generated closure match the corresponding Rust types generated by Crubit
(for example, `i32` for `int`, and `&Point` for `const Point&`).

## Passing types between Rust and C++ {#types}

### Primitive types {#primitives}

[Primitive numeric types and booleans](/docs/types/primitive.md)
pass directly by value between Rust and C++ (for example, `int` in C++
corresponds to `i32` in Rust, and `double` corresponds to `f64`).

### References and pointers {#references}

You can pass Rust references to C++ as `const T&` or raw pointers:

```live-snippet
cs/file:examples/cpp/inline_cpp/point.rs function:get_distance
```

> **WARNING:** Standard Rust lifetime rules apply. C++ code must not store or
> keep references or pointers after the `inline_cpp!` call returns.

## Common Use Cases {#use_cases}

### Calling and Defining C++ Templates {#templates}

Crubit does not automatically generate Rust bindings for uninstantiated C++
templates. With embedded C++, you can:

*   **Instantiate library templates**: Call templated functions or classes from
    included C++ headers inside `inline_cpp!`:

```live-snippet
cs/file:examples/cpp/inline_cpp/clamp.rs function:clamp_value
```

*   **Define helper templates in `global_cpp!`**: Define C++ template helpers at
    module scope, then instantiate them with concrete types in `inline_cpp!`:

```live-snippet
cs/file:examples/cpp/inline_cpp/math_helper.rs function:multiply_ints
```

## Common Errors {#errors}

`inline_cpp!` uses Crubit under the hood, so it can produce any error Crubit
could produce when bridging types.

### Missing parameter list or return type

`inline_cpp!` requires an explicit parameter list and return type arrow. If your
C++ snippet takes no arguments or returns nothing, specify `() -> void`:

```rust
let no_args_fn = inline_cpp! {
    () -> void {
        DoWork();
    }
};
no_args_fn();
```

Omitting the parameter list or return type results in an extraction syntax
error:

```
error: inline_cpp! block must start with a parameter list `(args)`
   --> src/lib.rs:10:5
    |
 10 |     inline_cpp! { DoWork(); }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
```

### Unsupported features and syntax limitations {#unsupported}

*   **Unmatched braces**: All `{}` braces inside embedded C++ blocks must be
    properly balanced. If a brace is unmatched (such as in complex preprocessor
    macros or unclosed string literals), the extraction preprocessor reports an
    unmatched delimiter error:

    ```
    error: Unmatched delimiter starting at src/lib.rs:10: Context around open brace:
    inline_cpp! { (int x) -> int { if (x > 0) { return x; }
    ```
