pub struct OwnedPtr<T, A: GameAllocator = NoOpAllocator> { /* private fields */ }Expand description
Pointer to a structure that the containing structure owns. You will generally use this to model structures in foreign memory when extending the game libraries. Do not use this in your own code as you’re risking all rusts safety reasoning.
§Safety
§OwnedPtr in FFI
When declaring definitions of C++ structs and functions that use this type, the author must ensure several invariants hold true:
-
This must be the only way to access the data it refers to without an
unsafeblock (not including theunsafeblock necessary to callFromStatic::instance). This means there may not be any other structs or methods that provide anOwnedPtror a reference to the underlying data.Although generally this means that the struct that h olds an
OwnedPtris the same one that “owns” the data it refers to in the sense of being responsible for constructing and destroying it, that’s not a hard requirement. In some cases, it may be more ergonomic to expose anOwnedPtr(or a reference) through a struct that’s easy to obtain and useNonNullfor the struct that actually has ownership. -
This must ensure that the backing memory is allocated by an allocator that’s compatible with
A. Note that all memory allocated in any way is compatible withNoOpAllocator, so this requirement only matters ifAis set explicitly.
§OwnedPtr and Drop
For any type T where Rust code might take ownership over an OwnedPtr<T>,
the author should be sure that T’s Drop implementation is correct. (This
is true in general for FFI types that Rust code can own.) There are two
concerns here:
-
Generally, C++ code will declare a specific destroy function for each type. In addition to calling the destructor method (
~T()), this destroys any fields as well. -
Rust drops fields in declaration order but C++ destroys them in reverse declaration order.
To mitigate these issues, all fields with non-trivial drop/destructor implementations should by wrapped in std::mem::ManuallyDrop. If the C++ code has a destroy method, it should be called from Drop::drop; otherwise, the implementation of Drop::drop should drop these fields in reverse declaration order.