4 ms·
The raw pointers are wrapped in `ComPtr` defined here: https://github.com/microsoft/winrt-rs/blob/master/src/com_ptr.rs https://github.com/microsoft/winrt-rs/bl
by Rusky 6y ago
The raw pointers are wrapped in `ComPtr` defined here: https://github.com/microsoft/winrt-rs/blob/master/src/com_ptr.rs https://github.com/microsoft/winrt-rs/blob/master/src/com_pt...
Those `ComPtr`s are then wrapped in convenience types that handle method dispatch, via code generated here: https://github.com/microsoft/winrt-rs/blob/master/crates/winmd/src/types/method.rs#L212-L224 https://github.com/microsoft/winrt-rs/blob/master/crates/win...
There is no integration with Rust Arc, but that's just because in COM/WinRT each object is in charge of its own allocation and ref-counting- AddRef and Release are just methods of IUnknown, the root of the interface hierarchy.
That particular trap doesn't really come up in COM/WinRT- COM objects only expose methods that pass around references to full objects. This is because a given object might exist in another process or even on another machine, in which case you are only holding a proxy created by the runtime.
So any references held by your event handler, to the button or its label, are ref-counted (though they may be weak references), and replacing an object is fine because it just decrements its refcount.
In the general case (e.g. implementing an interface yourself, or some other non-COM-based scenario), pornel's sibling comment is correct- just like with Rust's own Rc/Arc types, you can borrow from some particular ref-counted pointer and the compiler will ensure that it outlives those borrows, keeping the object alive.
- ridiculous_fish 6y agoHmm. Let's say I install an event handler: Application::Current.OnActivated = move |args| stuff(); and stuff() removes it: fn stuff() { Application::Current.OnActivated = None; } Rust lambdas are not COM objects and are not refcounted. In practice, what prevents the event handler from being deallocated while it is executing?
- Rusky 6y agoRight, a Rust lambda is not a COM object on its own, but by the same token you can't just stash one in a COM object's property either- COM object properties don't have a type for "Rust lambda," or "C++ lambda" for that matter. Instead you need to convert the lambda (from whatever language) into the type of that property- in this case some kind of Delegate, at which point it is ref-counted like any other COM object. So in this case, installing the handler increments the refcount, reading the handler back out to invoke it increments it again, the handler itself decrements it, and finally whoever invoked it drops their reference and the Delegate gets freed.