Making an agile version of a Windows Runtime delegate in C++/WinRT, part 6
cppdashboard.dev/r/2026/08/making-an-agile-version-of-a-windows-runtime-delegate-in-cpp-5This article discusses the challenges and solutions related to releasing a non-marshalable delegate on the correct thread in C++/WinRT. It highlights the importance of using a custom deleter with std::unique_ptr to avoid exceptions during construction.
From the article
It looked like we were done when we fixed the problem of releasing a non-marshalable delegate on the correct thread .
if (d.try_as<::INoMarshal>()) { void* p; if constexpr (std::is_reference_v<Delegate>) { p = winrt::detach_abi(d); } else { winrt::copy_to_abi(d, p); } return [p = std::unique_ptr<void, in_context_deleter>(p), token = get_context_token()](auto&&...args) { if (token == get_context_token()) { std::remove_reference_t<Delegate> d; winrt::copy_from_abi(d, p.get()); d(std::forward<decltype(args)>(args)...); } else { throw winrt::hresult_error(CO_E_NOT_SUPPORTED); } }; } The first part gets a raw ABI pointer, either by moving it out of the inbound delegate if we can, else by copying it from the inbound delegate. The reference count is owned by the raw pointer.
The second part…
Share this resource