macro_rules! cpp {
({$($body:tt)*}) => { ... };
([$($captures:tt)*] $($rest:tt)*) => { ... };
(unsafe $($tail:tt)*) => { ... };
}
Expand description
This macro is used to embed arbitrary C++ code.
There are two variants of the cpp!
macro. The first variant is used for
raw text inclusion. Text is included into the generated C++
file in the
order which they were defined, inlining module declarations.
cpp! {{
#include <stdint.h>
#include <stdio.h>
}}
The second variant is used to embed C++ code within Rust code. A list of variable names which should be captured are taken as the first argument, with their corresponding C++ type. The body is compiled as a C++ function.
This variant of the macro may only be invoked in expression context, and
requires an unsafe
block, as it is performing FFI.
let y: i32 = 10;
let mut z: i32 = 20;
let x: i32 = unsafe { cpp!([y as "int32_t", mut z as "int32_t"] -> i32 as "int32_t" {
z++;
return y + z;
})};
You can also put the unsafe keyword as the first keyword of the cpp!
macro, which
has the same effect as putting the whole macro in an unsafe
block:
let x: i32 = cpp!(unsafe [y as "int32_t", mut z as "int32_t"] -> i32 as "int32_t" {
z++;
return y + z;
});
§rust! pseudo-macro
The cpp!
macro can contain, in the C++ code, a rust!
sub-macro, which allows
the inclusion of Rust code in C++ code. This is useful to
implement callback or override virtual functions. Example:
trait MyTrait {
fn compute_value(&self, x : i32) -> i32;
}
cpp!{{
struct TraitPtr { void *a,*b; };
class MyClassImpl : public MyClass {
public:
TraitPtr m_trait;
int computeValue(int x) const override {
return rust!(MCI_computeValue [m_trait : &MyTrait as "TraitPtr", x : i32 as "int"]
-> i32 as "int" {
m_trait.compute_value(x)
});
}
}
}}
The syntax for the rust!
macro is:
rust!($uniq_ident:ident [$($arg_name:ident : $arg_rust_type:ty as $arg_c_type:tt),*]
$(-> $ret_rust_type:ty as $rust_c_type:tt)* {$($body:tt)*})
uniq_ident
is a unique identifier which will be used to name the extern
function