Closed JaiganeshKumaran closed 9 months ago
I've tagged a few project maintainers. If one of them is available to offer guidance and mentorship for this issue, they will reach out according to the contributing guide to discuss and agree on an approach.
@microsoft/cppwinrt-maintainers
FWIW the implements
class template is terribly complicated already. I would recommend you simply use your own fork for such dramatic customizations.
Overriding AddRef
and Release
are not sufficient because m_references
is also used for weak reference support.
Even static lifetime objects need to implement AddRef
and Release
so they can tear down at COM uninitialization. Otherwise, you get bugs where the DLL is unloaded (DllCanUnloadNow) because it lost track of its static lifetime objects.
Otherwise, you get bugs where the DLL is unloaded (DllCanUnloadNow) because it lost track of its static lifetime object
Well I can prevent unload and have it has a pinned DLL.
Currently I have complex cyclic object relationship where both objects must be alive at simultaneously. Weak references won't in my case because once get destructed while the other is alive. Having this feature would be really helpful so I can use a shared ref count for the two objects. Without it, I'm forced implement the ABI interfaces (or inherit from impl::produce<Derived, Interface>
), without the help of winrt::implements.
The WindowsAudioSession sample had a similar issue, which it solved by using embedded objects, although in the WindowsAudioSession case, it was clear which object was "primary" and which was "ancillary".
Another solution is to make the two objects explicitly one object under the hood, so their lifetimes are naturally coupled.
struct WidgetState
{
// Widget business logic goes here
};
struct DoodadState
{
// Doodad business logic goes here
};
struct CommonState
{
WidgetState widgetState;
DoodadState doodadState;
};
struct Widget : WidgetT<Widget>
{
std::shared_ptr<CommonState> const m_state;
Widget(std::shared_ptr<CommonState> const& state) : m_state(state) {}
void WidgetMethod1() { return m_state->widgetState.WidgetMethod1(); }
void WidgetMethod2() { return m_state->widgetState.WidgetMethod2(); }
};
struct Doodad : DoodadT<Doodad>
{
std::shared_ptr<CommonState> const m_state;
Doodad(std::shared_ptr<CommonState> const& state) : m_state(state) {}
void DoodadMethod1() { return m_state->doodadState.DoodadMethod1(); }
void DoodadMethod2() { return m_state->doodadState.DoodadMethod2(); }
};
std::pair<winrt::Widget, winrt::Doodad> MakePairedWidgetAndDoodad(Args args)
{
auto state = std::make_shared<CommonState>(args);
return { winrt::make<Widget>(state), winrt::make<Doodad>(state) };
}
Now you have a Widget and a Doodad whose lifetimes are coupled. Even if the app releases the last Widget, the WidgetState will remain alive until they also release the last Doodad.
This issue is stale because it has been open 10 days with no activity. Remove stale label or comment or this will be closed in 5 days.
@oldnewthing I don't want to have state separately; I want the sub-object itself to be alive. The embedded object solution is what I'm trying to do but implementing ABI interfaces directly is tedious, which is why I want winrt::implements to allow customisation of reference counting.
This issue is stale because it has been open 10 days with no activity. Remove stale label or comment or this will be closed in 5 days.
Currently every WinRT implementation type inheriting from implements automatically gets reference counting implemented. While you could override AddRef and Release, you still get the reference count field which cannot be removed. In some scenarios, you might want to eliminate the reference count field and do it all manually. These might include:
I propose adding a new marker type, winrt::no_ref_count which will remove the ref count field, as well as the default implementations of AddRef and Release.