Article

Making an agile version of a Windows Runtime delegate in C++/WinRT, part 6

The Old New Thing ·The Old New Thing ·Published 2026-07-27 ·5 min read

This 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


Discovered 2026-08-02 Source The Old New Thing Archive 2026-08 →