C++/WinRT: Consumption and Production

Previous: Getting Started

Whenever I’m introducing C++/WinRT I often end up talking about consumption and production of Windows Runtime interfaces. This is one of the defining features of C++/WinRT in terms of delivering productivity and reliability for both app and component developers, folks that are consuming and producing Windows Runtime APIs using standard C++.

Consider where we’ve come from. Let’s use the Windows.Foundation.IStringable interface as an example. A classic COM developer wanting to implement or produce a COM interface might write code that looks something like this:

#include "winrt/Windows.Foundation.h"
 
using namespace winrt;
using ABI::Windows::Foundation::IStringable;

struct Produce : implements<Produce, IStringable>
{
    HRESULT __stdcall abi_ToString(HSTRING * value) noexcept override
    {
        return WindowsCreateString(L"Hello world", 11, value);
    }
};

Already this is considerably simpler than it would otherwise be given that the implements class template does a lot of the heavy lifting, efficiently implementing IUnknown, IInspectable, IAgileObject, IWeakReferenceSource, and more. But I’m still left with having to implement the ToString virtual function, concern myself with error handling, and worry about the lifetime and nuances of various ABI types. A classic COM developer wanting to consume such a COM interface would likewise have to write code that looks something like this:

com_ptr<IStringable> s = make<Produce>();

HSTRING value = nullptr;
HRESULT hr = s->abi_ToString(&value);

if (hr != S_OK)
{
    // pain and suffering
}

printf("%ls\n", WindowsGetStringRawBuffer(value, nullptr));
WindowsDeleteString(value);

Again, this is simpler than it would otherwise be as I’m relying on the com_ptr class template and the make function template but I’m still left with some grungy error handling that is fraught with danger.

It is first and foremost these challenges and complications that disappear when you embrace C++/WinRT for consuming and producing Windows Runtime APIs with standard C++. Implementing the IStringable interface enters the world of modern C++:

using namespace winrt;
using Windows::Foundation::IStringable;

struct Produce : implements<Produce, IStringable>
{
    hstring ToString()
    {
        return L"Hello world";
    }
};

Notice the ABI interface is gone as I instead implement the projected IStringable interface with its ToString method that simply returns a lowercase hstring, a value types that takes care of deleting itself when it goes out of scope. No HRESULTs, no concern about exception handling, no awkward ABI functions for creating a string. A C++/WinRT developer can likewise use the same projected IStringable interface to consume such an interface quite simply:

IStringable s = make<Produce>();

hstring value = s.ToString();
printf("%ls\n", value.c_str());

The signature used to implement the ToString method is the same signature used to consume or call it. There’s no need for com_ptr and there’s no error handling or explicit resource management to worry about. This is the abstraction that sits at the heart of C++/WinRT and powers much of the rest of the language projection. This simplicity, an embrace of modern ISO C++, is what makes C++/WinRT such a groundbreaking tool for the Windows developer.

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: Working with Implementations

4 thoughts on “C++/WinRT: Consumption and Production

  1. Sunil Joshi

    Only problem is that there is tooling to automatically stub out virtuals but because these aren’t virtuals you have to lookup and write the signatures out manually.

    Reply
  2. Jack Detrick

    Consider a VS 2015 Windows Universal Solution with two projects: , one C++/CX and one C++/winrt.. In order for the C++/CX project to have a reference to the C++/winrt.it needs to find a winmd file.. Is there a c++.winrt such option?

    Reply
    1. Kenny Kerr Post author

      Although C++/WinRT allows you to code implementations it does not yet provide any support for producing the necessary metadata. That will be available in a future update.

      Reply

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