July 30th, 2026
likemind blown2 reactions

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

Over half of the time we spent trying to make an agile version of a Windows Runtime delegate in C++/WinRT was dealing with the case of a delegate that declares non-marshalability. But how much does it matter?

I looked at the three major C++ implementations of the Windows Runtime: C++/WinRT, C++/CX, and WRL.

The C++/WinRT implementation has an optimization for IAgile­Object, but for objects that aren’t agile, it just goes directly to agile_ref without checking for INoMarshal. This means that a delegate that declares non-marshability will always be rejected by C++/WinRT when used as an event handler.

The C++/CX implementation lazy-creates the agile reference to the original delegate when the wrapper is used from a different apartment. If the original delegate is non-marshalable, it means that the CO_E_NOT­SUPPORTED is produced only when the wrapper is used in a way that requires a marshalable delegate.

The WRL implementation does not have an optimization for IAgile­Object, although it mentions it as a possible optimization. It always creates the agile reference eagerly, which means that if the original delegate is non-marshalable, it cannot be added to an agile event source.

Okay, so let’s summarize in a table.

Event source C++/WinRT C++/CX WRL Our version
single-threaded multi-threaded
Optimize agile delegates Yes Yes N/A No Yes
Avoid wrapping agile delegates Yes No Never wraps No Yes
Agile reference creation Eager Lazy Never Eager Eager
Non-marshalable delegates Rejected Allowed if used
non-agile-ly
Allowed (always
used non-agile-ly)
Rejected Allowed if used
non-agile-ly

Now, maybe you think we are working too hard. (Maybe we are.) In which case you can remove support for whatever cases you feel you don’t need.

Topics

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

1 comment

Sort by :
  • GL 3 hours ago

    The C++/WinRT implementation looks pretty dangerous as it ignores the return value of RoGetAgileReference. Two documented failure modes that should be handled at that call site are out of memory and INoMarshal, either of which would cause make_agile_delegate to return a non-agile object.

    I’d suggest throwing an exception instead.