diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 13c6eba23..04598775a 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -22,6 +22,7 @@ SPDX-License-Identifier: MIT OR Apache-2.0 - [Nested Objects](./concepts/nested_objects.md) - [Inheritance & Overriding](./concepts/inheritance.md) - [Casting](./concepts/casting.md) + - [Instantiating in Rust](./concepts/instantiating_in_rust.md) - [Reference: the bridge module](./bridge/index.md) - [`extern "RustQt"`](./bridge/extern_rustqt.md) - [`extern "C++Qt"`](./bridge/extern_cppqt.md) diff --git a/book/src/concepts/instantiating_in_rust.md b/book/src/concepts/instantiating_in_rust.md new file mode 100644 index 000000000..a9262383a --- /dev/null +++ b/book/src/concepts/instantiating_in_rust.md @@ -0,0 +1,55 @@ + + +# Instantiating `QObject`s directly in Rust + +Your `QObject` types will most likely be instantiated via QML, but it is possible to create them in Rust via a template. +By adding + +```rust,ignore +#[namespace = "rust::cxxqtlib1"] +unsafe extern "C++" { + include!("cxx-qt-lib/common.h"); + + #[cxx_name = "make_unique"] + #[doc(hidden)] + fn myobject_make_unique() -> UniquePtr; +} +``` + +You can directly create an instance of your object wrapped in a `UniquePtr` within Rust, should you wish. +The included header file contains some wrapper templates for constructing `unique_ptr`, `shared_ptr` and `*T`. +By exposing this to the bridge with the correct namespace, constructing these structs is possible in Rust. +These helper methods live in cxx-qt-lib, and thus need to be included, and this is also why the namespace is necessary. +These are helper functions defined by CXX-Qt, and are ***Not the same as*** `std::make_unique`, etc... + +## Passing Parameters + +You can also supply the constructor with parameters via these helper methods, +but you should ensure that any constructors with different arguments have different names in Rust, via renaming. + +```rust,ignore +#[namespace = "rust::cxxqtlib1"] +unsafe extern "C++" { + include!("cxx-qt-lib/common.h"); + + #[rust_name = "new_my_object_with_parent"] + fn make_unique(parent: *mut QObject) -> UniquePtr; + + // Overloading without the parent parameter + #[rust_name = "new_my_object"] + fn make_unique() -> UniquePtr; +} +``` + +## Possible Methods + +| Name | C++ Return Type | Rust Return Type | +|---------------|-----------------|------------------| +| `make_unique` | `unique_ptr` | `UniquePtr` | +| `make_shared` | `shared_ptr` | `SharedPtr` | +| `new_ptr` | `*T` | `*mut T` | diff --git a/book/src/getting-started/1-qobjects-in-rust.md b/book/src/getting-started/1-qobjects-in-rust.md index 11eaaeb79..d5967b3f8 100644 --- a/book/src/getting-started/1-qobjects-in-rust.md +++ b/book/src/getting-started/1-qobjects-in-rust.md @@ -70,6 +70,8 @@ In comparison to a normal opaque CXX class, the mapping between the `QObject` su The `QObject` subclass is its own type in Rust, as well as in C++. When such a `QObject` is instantiated, it will always also construct an instance of the Rust `struct`. +The `QObject`s Rust struct can also be directly constructed via a `UniquePtr` in Rust, but this is a less common use case, +see [here](../concepts/instantiating_in_rust.md) for more information. The `QObject` can then refer to the underlying Rust `struct` for property access. Any behavior of this `QObject` subclass will also be defined in Rust, e.g. using the [`#[qinvokable]`](../bridge/extern_rustqt.html#invokables) attribute. The Rust implementation also has access to the underlying Rust `struct` to modify any Rust data.