Trait cxx::ExternType
source · Expand description
A type for which the layout is determined by its C++ definition.
This trait serves the following two related purposes.
Safely unifying occurrences of the same extern type
ExternType
makes it possible for CXX to safely share a consistent Rust
type across multiple #[cxx::bridge] invocations that refer to a common
extern C++ type.
In the following snippet, two #[cxx::bridge] invocations in different
files (possibly different crates) both contain function signatures involving
the same C++ type example::Demo
. If both were written just containing
type Demo;
, then both macro expansions would produce their own separate
Rust type called Demo
and thus the compiler wouldn’t allow us to take the
Demo
returned by file1::ffi::create_demo
and pass it as the Demo
argument accepted by file2::ffi::take_ref_demo
. Instead, one of the two
Demo
s has been defined as an extern type alias of the other, making them
the same type in Rust. The CXX code generator will use an automatically
generated ExternType
impl emitted in file1 to statically verify that in
file2 crate::file1::ffi::Demo
really does refer to the C++ type
example::Demo
as expected in file2.
// file1.rs
#[cxx::bridge(namespace = "example")]
pub mod ffi {
unsafe extern "C++" {
type Demo;
fn create_demo() -> UniquePtr<Demo>;
}
}
// file2.rs
#[cxx::bridge(namespace = "example")]
pub mod ffi {
unsafe extern "C++" {
type Demo = crate::file1::ffi::Demo;
fn take_ref_demo(demo: &Demo);
}
}
Integrating with bindgen-generated types
Handwritten ExternType
impls make it possible to plug in a data structure
emitted by bindgen as the definition of a C++ type emitted by CXX.
By writing the unsafe ExternType
impl, the programmer asserts that the C++
namespace and type name given in the type id refers to a C++ type that is
equivalent to Rust type that is the Self
type of the impl.
mod folly_sys; // the bindgen-generated bindings
use cxx::{type_id, ExternType};
unsafe impl ExternType for folly_sys::StringPiece {
type Id = type_id!("folly::StringPiece");
type Kind = cxx::kind::Opaque;
}
#[cxx::bridge(namespace = "folly")]
pub mod ffi {
unsafe extern "C++" {
include!("rust_cxx_bindings.h");
type StringPiece = crate::folly_sys::StringPiece;
fn print_string_piece(s: &StringPiece);
}
}
// Now if we construct a StringPiece or obtain one through one
// of the bindgen-generated signatures, we are able to pass it
// along to ffi::print_string_piece.
Required Associated Types
sourcetype Id
type Id
A type-level representation of the type’s C++ namespace and type name.
This will always be defined using type_id!
in the following form:
type Id = cxx::type_id!("name::space::of::TypeName");
sourcetype Kind: Kind
type Kind: Kind
Either cxx::kind::Opaque
or cxx::kind::Trivial
.
A C++ type is only okay to hold and pass around by value in Rust if its move constructor is trivial and it has no destructor. In CXX, these are called Trivial extern C++ types, while types with nontrivial move behavior or a destructor must be considered Opaque and handled by Rust only behind an indirection, such as a reference or UniquePtr.
If you believe your C++ type reflected by this ExternType impl is indeed fine to hold by value and move in Rust, you can specify:
type Kind = cxx::kind::Trivial;
which will enable you to pass it into C++ functions by value, return it
by value, and include it in struct
s that you have declared to
cxx::bridge
. Your claim about the triviality of the C++ type will be
checked by a static_assert
in the generated C++ side of the binding.
Implementations on Foreign Types
sourceimpl ExternType for bool
impl ExternType for bool
sourceimpl ExternType for u8
impl ExternType for u8
sourceimpl ExternType for u16
impl ExternType for u16
sourceimpl ExternType for u32
impl ExternType for u32
sourceimpl ExternType for u64
impl ExternType for u64
sourceimpl ExternType for usize
impl ExternType for usize
sourceimpl ExternType for i8
impl ExternType for i8
sourceimpl ExternType for i16
impl ExternType for i16
sourceimpl ExternType for i32
impl ExternType for i32
sourceimpl ExternType for i64
impl ExternType for i64
sourceimpl ExternType for isize
impl ExternType for isize
sourceimpl ExternType for f32
impl ExternType for f32
sourceimpl ExternType for f64
impl ExternType for f64
sourceimpl ExternType for String
Available on crate feature alloc
only.
impl ExternType for String
alloc
only.