C++/WinRT: Working with Implementations

Previous: Consumption and Production

Consider the following simple class that implements both the IStringable interface and the IClosable interface. These interfaces were chosen for their simplicity and don’t hold any special status in C++/WinRT (unlike C++/CX).

using namespace Windows::Foundation;

struct Sample : implements<Sample, IStringable, IClosable>
{
    hstring ToString()
    {
        return L"Sample";
    }

    void Close()
    {
    }
};

Clearly this class implements IStringable and IClosable but how do I go from an implementation to an IStringable or IClosable object that I can use or return as part of the projection? There are actually a few options. I alluded to the make function template in the previous installment. The make function returns the first interface implemented by Sample:

IStringable a = make<Sample>();

This is most useful if I’m passing the result directly to a caller. Alternatively, I can specify another interface that the implementation provides:

IClosable b = make<Sample, IClosable>();

Sometimes I might need to get the implementation right away and only later return an interface to some caller. In that case, the make_self function template is what I need:

com_ptr<Sample> c = make_self<Sample>();

Notice that I’ve effectively stepped out of the projection. The Sample class is not part of the projection. It’s my implementation, but I can certainly call its implementation methods directly (without the overhead of a virtual function call):

com_ptr<Sample> c = make_self<Sample>();
hstring h = c->ToString();

Even though the ToString method uses the same signature as the projected IStringable method, here I’m calling that non virtual method directly without crossing the ABI. Since the com_ptr simply holds a pointer to the Sample class, I can also access any other internal details of the implementation.

Finally, if I have an interface and I happen to know that it’s my implementation then I can get back to the implementation using the to_impl function template:

IStringable a = make<Sample>();

Sample * impl = to_impl<Sample>(a);

hstring h = impl->ToString();

Again, this can be used to avoid vcalls and get directly at the implementation but the original object still holds the reference. So if I want to hold on to it I might want to do something like this:

com_ptr<Sample> impl;
impl.copy_from(to_impl<Sample>(a));

The copy_from function will ensure that AddRef is called.

This is just a few of the ways you can interact with and manage implementations. Join me next time as we continue to explore C++/WinRT. Give C++/WinRT a try today. Got a question? Post it here and we’ll do our best to help.

Next: Fun with Agility

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s