May 1st, 2023

A quick note about WRL’s Chain­Interfaces template class

The Windows Runtime C++ Template Library (commonly known as WRL) contains a template class called Chain­Interfaces. The documentation for Chain­Interfaces talks about what it does but doesn’t tell you why it’s there or when you should use it.

The purpose of Chain­Interfaces is to be included among the template arguments to the WRL Runtime­Class and Implements template classes to indicate that you have a sequence (“chain”) of interfaces where each one extends the previous one.

For example, the IFileSystemBindData2 interface extends the IFileSystemBindData interface. If you want to use WRL to implement an object that implements both interfaces, you would write

namespace wrl = Microsoft::WRL;

struct MyFileSystemBindData :
    wrl::RuntimeClass<
        wrl::RuntimeClassFlags<wrl::ClassicCom>,
        wrl::ChainInterfaces<IFileSystemBindData2, IFileSystemBindData>
    >
{
    ⟦ implementation elided for expository purposes ⟧
}

Note that you list the Chain­Interfaces template parameters from most derived to least derived. Fortunately, if you get the order wrong, you get a compile-time error.

Topics
Code

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.

2 comments

Discussion is closed. Login to edit/delete existing comments.

  • The Himalayas

    I must be missing something. Can the following not achieve the same thing?

    namespace wrl = Microsoft::WRL;

    struct MyFileSystemBindData :
    wrl::RuntimeClass<
    wrl::RuntimeClassFlags,
    IFileSystemBindData2,
    IFileSystemBindData

    >
    {
    ⟦ implementation elided for expository purposes ⟧
    }

    The implementation of IFileSystemBindData2 covers IFileSystemBindData, since the former extends the latter.

    If so, why do we need Chain­Interfaces?

  • skSdnW

    I guess this is the modern version of QITABENTMULTI used with QISearch. That macro was error prone but the generated code is smaller than what templates give you.