Add Ref
and OutRef
to enhance COM authoring support
#3025
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This update introduces a number of improvements to the
implement
andinterface
macros as well as thewindows-core
crate that work together to enhance support for COM interface declarations and implementations as well as general FFI/ABI support.Consider the following C++ function signature:
HRESULT __stdcall DllGetActivationFactory(HSTRING, IActivationFactory**)
This function must be exported by DLLs for WinRT (COM) support. The ABI requirements are such that the
HSTRING
andIActivationFactory
types are "borrowed" in the sense that neither the caller nor the callee must free or drop those values as part of the call itself. This leads to Rust developers having to write something like this:The implementation is then forced to carefully consider and manage lifetimes and transfer ownership and is easy to get wrong.
The
Ref
andOutRef
types represent borrowed types, providing the same memory layout but also offer lifetime management and conveniences to make dealing with in and out parameters safe and convenient:Ref
implements theDeref
trait that returns a reference to the borrowed type whileOutRef
provides thewrite
method that will overwrite the memory location with the given value. Thewrite
method can only be called once and checks for null. It also provides theis_null
method if you need to conditionally support optional out parameters.The
interface
macro will also generate bindings forRef
andOutRef
that behave like the bindings generated by thewindows-bindgen
crate, making it easier to call such interface methods naturally from Rust. This leverages the newParamMut
trait that compliments the existingParam
trait for handling out parameters. It takes care of dealing with uninitialized memory in out parameters as well as dropping&mut
values in Rust to avoid leaks.In addition, the
interface
macro now supportsResult
return types for convenience. The underlying virtual function will still return anHRESULT
but theinterface
andimplement
macros will automatically translate that for you: