mirror of
https://gitee.com/openharmony/third_party_rust_cxx
synced 2024-11-23 23:29:50 +00:00
Document ExternType trait
This commit is contained in:
parent
a62cca2268
commit
094db3ecea
@ -1,4 +1,108 @@
|
||||
/// A type for which the layout is determined by its C++ definition.
|
||||
///
|
||||
/// This trait serves the following two related purposes.
|
||||
///
|
||||
/// <br>
|
||||
///
|
||||
/// ## 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.
|
||||
///
|
||||
/// ```no_run
|
||||
/// // file1.rs
|
||||
/// # mod file1 {
|
||||
/// #[cxx::bridge(namespace = example)]
|
||||
/// pub mod ffi {
|
||||
/// extern "C" {
|
||||
/// type Demo;
|
||||
///
|
||||
/// fn create_demo() -> UniquePtr<Demo>;
|
||||
/// }
|
||||
/// }
|
||||
/// # }
|
||||
///
|
||||
/// // file2.rs
|
||||
/// #[cxx::bridge(namespace = example)]
|
||||
/// pub mod ffi {
|
||||
/// extern "C" {
|
||||
/// type Demo = crate::file1::ffi::Demo;
|
||||
///
|
||||
/// fn take_ref_demo(demo: &Demo);
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
///
|
||||
/// <br><br>
|
||||
///
|
||||
/// ## Integrating with bindgen-generated types
|
||||
///
|
||||
/// Handwritten `ExternType` impls make it possible to plug in a data structure
|
||||
/// emitted by bindgen as the definition of an opaque 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.
|
||||
///
|
||||
/// ```no_run
|
||||
/// # const _: &str = stringify! {
|
||||
/// mod folly_sys; // the bindgen-generated bindings
|
||||
/// # };
|
||||
/// # mod folly_sys {
|
||||
/// # #[repr(transparent)]
|
||||
/// # pub struct StringPiece([usize; 2]);
|
||||
/// # }
|
||||
///
|
||||
/// use cxx::{type_id, ExternType};
|
||||
///
|
||||
/// unsafe impl ExternType for folly_sys::StringPiece {
|
||||
/// type Id = type_id!("folly::StringPiece");
|
||||
/// }
|
||||
///
|
||||
/// #[cxx::bridge(namespace = folly)]
|
||||
/// pub mod ffi {
|
||||
/// 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.
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
pub unsafe trait ExternType {
|
||||
/// 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:
|
||||
///
|
||||
/// ```
|
||||
/// # struct TypeName;
|
||||
/// # unsafe impl cxx::ExternType for TypeName {
|
||||
/// type Id = cxx::type_id!("name::space::of::TypeName");
|
||||
/// # }
|
||||
/// ```
|
||||
type Id;
|
||||
}
|
||||
|
||||
|
@ -389,7 +389,10 @@ pub use crate::cxx_vector::CxxVector;
|
||||
pub use crate::exception::Exception;
|
||||
pub use crate::extern_type::ExternType;
|
||||
pub use crate::unique_ptr::UniquePtr;
|
||||
pub use cxxbridge_macro::{bridge, type_id};
|
||||
pub use cxxbridge_macro::{bridge};
|
||||
|
||||
/// For use in impls of the `ExternType` trait. See [`ExternType`].
|
||||
pub use cxxbridge_macro::type_id;
|
||||
|
||||
// Not public API.
|
||||
#[doc(hidden)]
|
||||
|
@ -1,13 +1,13 @@
|
||||
error[E0271]: type mismatch resolving `<here::StringPiece as cxx::extern_type::ExternType>::Id == (cxx::f, cxx::o, cxx::l, cxx::l, cxx::y, (), cxx::B, cxx::y, cxx::t, cxx::e, cxx::R, cxx::a, cxx::n, cxx::g, cxx::e)`
|
||||
--> $DIR/wrong_type_id.rs:11:9
|
||||
|
|
||||
11 | type ByteRange = crate::here::StringPiece;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected a tuple with 15 elements, found one with 17 elements
|
||||
|
|
||||
::: $WORKSPACE/src/extern_type.rs:6:41
|
||||
|
|
||||
6 | pub fn verify_extern_type<T: ExternType<Id = Id>, Id>() {}
|
||||
| ------- required by this bound in `cxx::extern_type::verify_extern_type`
|
||||
|
|
||||
= note: expected tuple `(cxx::f, cxx::o, cxx::l, cxx::l, cxx::y, (), cxx::B, cxx::y, cxx::t, cxx::e, cxx::R, cxx::a, cxx::n, cxx::g, cxx::e)`
|
||||
found tuple `(cxx::f, cxx::o, cxx::l, cxx::l, cxx::y, (), cxx::S, cxx::t, cxx::r, cxx::i, cxx::n, cxx::g, cxx::P, cxx::i, cxx::e, cxx::c, cxx::e)`
|
||||
--> $DIR/wrong_type_id.rs:11:9
|
||||
|
|
||||
11 | type ByteRange = crate::here::StringPiece;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected a tuple with 15 elements, found one with 17 elements
|
||||
|
|
||||
::: $WORKSPACE/src/extern_type.rs:110:41
|
||||
|
|
||||
110 | pub fn verify_extern_type<T: ExternType<Id = Id>, Id>() {}
|
||||
| ------- required by this bound in `cxx::extern_type::verify_extern_type`
|
||||
|
|
||||
= note: expected tuple `(cxx::f, cxx::o, cxx::l, cxx::l, cxx::y, (), cxx::B, cxx::y, cxx::t, cxx::e, cxx::R, cxx::a, cxx::n, cxx::g, cxx::e)`
|
||||
found tuple `(cxx::f, cxx::o, cxx::l, cxx::l, cxx::y, (), cxx::S, cxx::t, cxx::r, cxx::i, cxx::n, cxx::g, cxx::P, cxx::i, cxx::e, cxx::c, cxx::e)`
|
||||
|
Loading…
Reference in New Issue
Block a user