C++/WinRT: Producing Async Objects

Previous: Handling Async Completion

Now that we’ve explored the async interfaces and some completion mechanics in general, let’s turn our attention to creating or producing implementations of those four async interfaces. As we’ve already learned, implementing WinRT interfaces with C++/WinRT is very simple. I might for example implement IAsyncAction as follows:

struct MyAsync : implements<MyAsync, IAsyncAction, IAsyncInfo>
{
    // IAsyncInfo members...
    uint32_t Id() const;
    AsyncStatus Status() const;
    HRESULT ErrorCode() const;
    void Cancel() const;
    void Close() const;

    // IAsyncAction members...
    void Completed(AsyncActionCompletedHandler const& handler) const;
    AsyncActionCompletedHandler Completed() const;
    void GetResults() const;
}; 

The difficulty comes when you consider how you might implement those methods. While it is not hard to imagine some implementation, it is almost impossible to do it correctly without first reverse engineering how the existing language projections actually implement them. You see, the WinRT async pattern only works if everyone implements these interfaces using a very specific state machine and in exactly the same way. Each language projection makes the same assumptions about how this state machine is implemented and if you happen to implement it in a slightly different way, then bad things will happen.

Thankfully, you don’t have to worry about this because each language projection, with the exception of C++/CX, already implements this correctly for you. Here’s a complete implementation of IAsyncAction thanks to C++/WinRT’s coroutine support:

IAsyncAction CopyAsync()
{
    co_return;
}

Now this isn’t a particularly interesting implementation, but it is very educational and a good example of just how much C++/WinRT is doing for you. Since this is a complete implementation, we can use it to exercise some of what we’ve learned thus far. The CopyAsync function above is a coroutine. The coroutine’s return type is used to stitch together an implementation of both IAsyncAction and IAsyncInfo and the C++ compiler brings it to life at just the right moment. We’ll explore some of those details later, but for now let’s observe how this coroutine works. Consider the following console app:

IAsyncAction CopyAsync()
{
    co_return;
}

int main()
{
    IAsyncAction async = CopyAsync();

    async.get();
}

The main function calls the CopyAsync function, which returns an IAsyncAction. If you forget for a moment what the CopyAsync function’s body or definition looks like, it should be evident that it is just a function that returns an IAsyncAction object. We can therefore use it in all the ways that we’ve already learned.

A coroutine (of this sort) must have a co_return statement or a co_await statement. It may of course have multiple, but it must have at least one of these in order to actually be a coroutine. As you might expect, a co_return statement does not introduce any kind of suspension or asynchrony. Therefore, this CopyAsync function produces an IAsyncAction that completes immediately or synchronously. I can illustrate this as follows:

IAsyncAction Async()
{
    co_return;
}

int main()
{
    IAsyncAction async = Async();
    assert(async.Status() == AsyncStatus::Completed);
}

The assertion is guaranteed to be true. There is no race here. Since CopyAsync is just a function, the caller is blocked until it returns and the first opportunity for it to return happens to be the co_return statement. What this means is that if you have some async contract that you need to implement, but the implementation does not actually need to introduce any asynchrony, then it can simply return the value directly and without blocking or introducing a context switch. Consider a function that downloads and then returns a cached value:

hstring m_cache;

IAsyncOperation<hstring> ReadAsync()
{
    if (m_cache.empty())
    {
        // Download and cache value...
    }

    co_return m_cache;
}

int main()
{
    hstring message = ReadAsync().get();
    printf("%ls\n", message.c_str());
}

The first time ReadAsync is called, the cache is presumably empty, and the result is downloaded. Presumably this will suspend the coroutine itself while this takes place. We’ll talk more about how exactly suspension works a little later. Suspension implies that execution returns to the caller. The caller is handed an async object that has not in fact completed, hence the need to somehow wait for completion.

The beauty of coroutines is that there’s a single abstraction both for producing async objects and for consuming those same async objects. An API or component author might implement an async method as described above, but an API consumer or app developer may also use coroutines to call and wait for their completion. Let’s now rewrite the main function above to use a coroutine to do the waiting:

IAsyncAction MainAsync()
{
    hstring result = co_await ReadAsync();
    printf("%ls\n", result.c_str());
}

int main()
{
    MainAsync().get();
}

I have essentially taken the body of the old main function and moved it into the MainAsync coroutine. The main function uses the get method to prevent the app from terminating while the app completes asynchronously. The MainAsync function has something new and that’s the co_await statement. Rather than using the get method to block the calling thread until ReadAsync completes, the co_await statement is used to wait for the ReadAsync function to complete in a cooperative or non-blocking manner. This is what I meant by a suspension point. The co_await statement represents a suspension point. This app only calls ReadAsync once, but you can imagine it being called multiple times in a more interesting app. The first time it gets called, the MainAsync coroutine will actually suspend and return control to its caller. The second time its called, it will not suspend at all but rather return the value directly.

Coroutines are very new to many C++ developers so don’t feel bad if this still seems rather magical. We’ll continue to explore coroutines over the next few installments and these concepts should become quite clear. The good news is that you already know enough to begin to make effective use of coroutines to consume async APIs provided by Windows. For example, you should be able to reason about how the following console app works:

#include "winrt/Windows.Web.Syndication.h"

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Web::Syndication;

IAsyncAction MainAsync()
{
    Uri uri(L"https://kennykerr.ca/feed");
    SyndicationClient client;
    SyndicationFeed feed = co_await client.RetrieveFeedAsync(uri);

    for (auto&& item : feed.Items())
    {
        hstring title = item.Title().Text();

        printf("%ls\n", title.c_str());
    }
}

int main()
{
    init_apartment();
    MainAsync().get();
}

Give it a try right now and see just how much fun it is to use modern C++ on Windows.

C++/WinRT: Handling Async Completion

Previous: Understanding Async

Now that you have a handle on async interfaces in general, let’s begin to drill down into how they work in a bit more detail. Assuming you’re not satisfied with the blocking wait provided by the get method, what other options are there? We’ll soon switch gears and focus entirely on coroutines, but for the moment let’s take a closer look at those async interfaces to see what they offer. Both the coroutine support, as well as the get method we looked at last time, rely on the contract and state machine implied by those interfaces. I won’t go into too much detail because you really don’t need to know all that much about it, but let’s explore the basics so that it will at least be familiar if you do ever have to dive in and use them directly for something more out of the ordinary.

All four of the async interfaces logically derive from the IAsyncInfo interface. There’s very little you can do with IAsyncInfo and it’s regrettable that it even exists since it adds a bit of overhead. The only IAsyncInfo members that you should really consider are Status, which can tell you whether the async method has completed, and Cancel, which may be used to request cancellation of a long-running operation whose result is no longer needed. I nitpick this design because I really like the async pattern in general and just wish it were perfect because it is so very close.

The Status member can be useful if you need to determine whether an async method has completed without actually waiting for it. Here’s an example:

auto async = ReadAsync();

if (async.Status() == AsyncStatus::Completed)
{
    auto result = async.GetResults();
    printf("%ls\n", result.c_str());
}

Each of the four async interfaces, not IAsyncInfo itself, provide individual versions of the GetResults method that should only be called once you’ve determined that the async method has completed. Don’t confuse this with the get method provided by C++/WinRT. While GetResults is implemented by the async method itself, get is implemented by C++/WinRT. GetResults will not block if the async method is still running and will likely throw an hresult_illegal_method_call exception if called prematurely. You can no doubt begin to imagine how the blocking get method is implemented. Conceptually, it looks something like this:

auto get() const
{
    if (Status() != AsyncStatus::Completed)
    {
        // wait for completion somehow...
    }

    return GetResults();
}

The actual implementation is a bit more complicated, but this captures the gist of it. The point here is that GetResults is called regardless of whether it’s an IAsyncOperation, which returns a value, or IAsyncAction, which does not. The reason for this is that GetResults is responsible for propagating any error that may have occurred within the implementation of the async method and will rethrow an exception as needed. This is why I could simply wrap the get call inside a try-block and catch exceptions quite simply in my previous installment.

The question that remains is how the caller can wait for completion. Let’s write a non-member get function to see what’s involved. I’ll start with this basic outline, inspired by the conceptual get method above:

template <typename T>
auto get(T const& async)
{
    if (async.Status() != AsyncStatus::Completed)
    {
        // wait for completion somehow...
    }

    return async.GetResults();
}

I want this function template to work with all four of the async interfaces, so I’ll use the return statement unilaterally. Special provision is made in the C++ language for genericity and we can be thankful for that.

Each of the four async interfaces provides a unique Completed member that may be used to register a callback – called a delegate – that will be called when the async method completes. In most cases, C++/WinRT will automatically create the delegate for you. All you must do is provide some function-like handler and a lambda is usually the simplest:

async.Completed([](auto&& async, AsyncStatus status)
{
    // It's done!
});

The type of the delegate’s first parameter will be that of the async interface that just completed, but keep in mind that completion should be regarded as a simple signal. In other words, don’t stuff a bunch of code inside the Completed handler. Essentially, you should regard it as a noexcept handler because the async method will not itself know what to do with any failure occurring inside this handler. So what can we do?

Well, I might simply notify a waiting thread using an event. Here’s what our get function might look like:

template <typename T>
auto get(T const& async)
{
    if (async.Status() != AsyncStatus::Completed)
    {
        handle signal = CreateEvent(nullptr, true, false, nullptr);

        async.Completed([&](auto&&, auto&&)
        {
            SetEvent(signal.get());
        });

        WaitForSingleObject(signal.get(), INFINITE);
    }

    return async.GetResults();
}

C++/WinRT’s get methods use a condition variable with a slim reader/writer lock because it’s slightly more efficient. Such a variant might look something like this:

template <typename T>
auto get(T const& async)
{
    if (async.Status() != AsyncStatus::Completed)
    {
        slim_mutex m;
        slim_condition_variable cv;
        bool completed = false;

        async.Completed([&](auto&&, auto&&)
        {
            {
                slim_lock_guard const guard(m);
                completed = true;
            }

            cv.notify_one();
        });

        slim_lock_guard guard(m);
        cv.wait(m, [&] { return completed; });
    }

    return async.GetResults();
}

You can of course use the C++ standard library’s mutex and condition variable if you prefer. The point here is simply that the Completed handler is your hook to wiring up async completion and it can be done quite generically.

Naturally, there’s no reason for you to write your own get function and more than likely coroutines will be much simpler and more versatile in general. Still, I hope this helps you to appreciate some of the power and flexibility in the Windows Runtime.

That’s all I have time for today. Join me next time as we explore more about async in the Windows Runtime.

C++/WinRT: Understanding Async

Previous: Working with Strings

The Windows Runtime has a relatively simple async model in the sense that, like everything else in the Windows Runtime, it is focused on allowing components to expose async methods and making it simple for apps to call those async methods. It does not in itself provide a concurrency runtime or even anything in the way of building blocks for producing or consuming async methods. Instead, all of that is left up to the individual language projections. This is as it should be and is not meant to trivialize the Windows Runtime’s async pattern. It is no small feat to implement this pattern correctly. Of course, it also means that a developer’s perception of async in the Windows Runtime is very heavily influenced by their language of choice. A developer that has only ever used C++/CX might for example wrongly, but understandably, assume that async is a hot mess.

The ideal concurrency framework for the C# developer will be different to the ideal concurrency library for the C++ developer. The role of the language projection then is to take care of the mechanics of the async pattern and provide a natural bridge to a language-specific implementation.

Coroutines are the preferred abstraction for both implementing and calling async methods in C++, but first let’s make sure we understand how the async model works. Consider a class with a single static method that looks something like this:

struct Sample
{
    Sample() = delete;

    static Windows::Foundation::IAsyncAction CopyAsync();
};

Async methods end with “Async” by convention, so you might think of this as the Copy async method. There might be a blocking or synchronous alternative that is simply called Copy. It is conceivable that a caller might want a blocking Copy method for use by a background thread and a non-blocking, or asynchronous, method for use by a UI thread that cannot afford to block for fear of appearing unresponsive.

At first, the CopyAsync method may seem quite simple to call. I might write the following C++ code:

IAsyncAction async = Sample::CopyAsync();

As you might imagine, the resulting IAsyncAction is not actually the ultimate result of the async method, even as it is the result of calling the CopyAsync method in a traditional procedural manner. The IAsyncAction is the object that a caller may use to wait upon the result synchronously or asynchronously, depending on the situation. Along with IAsyncAction, there are three other well-known interfaces that follow a similar pattern and offer different features for the callee to communicate information back to the caller. The following table provides a comparison of the four async interfaces.

In C++ terms, the interfaces can be expressed as follows:

namespace Windows::Foundation
{
    struct IAsyncAction;

    template <typename Progress>
    struct IAsyncActionWithProgress;

    template <typename Result>
    struct IAsyncOperation;

    template <typename Result, typename Progress>
    struct IAsyncOperationWithProgress;
}

IAsyncAction and IAsyncActionWithProgress can be waited upon to determine when the async method completes, but these interfaces do not offer any observable result or return value directly. IAsyncOperation and IAsyncOperationWithProgress, on the other hand, expect the Result type parameter to indicate the type of result that can be expected when the async method completes successfully. Finally, IAsyncActionWithProgress and IAsyncOperationWithProgress expect the Progress type parameter to indicate the type of progress information that can be expected periodically for long-running operations up until the async method completes.

There are a few ways to wait upon the result of an async method. I won’t describe them all here since that would turn this into a very long article. Instead, I’ll save those for next time so that I can give them each the attention they deserve. While there are a variety of ways to handle async completion, there are only two that I recommend. Those two are the async.get() method, which performs a blocking wait, and the co_await async expression, which performs a cooperative wait in the context of a coroutine. Neither is better than the other as they simply serve different purposes. Let’s look at blocking wait today.

As I mentioned, a blocking wait can be achieved using the get() method as follows:

IAsyncAction async = Sample::CopyAsync();

async.get();

There’s seldom any value in holding on to the async object and the following form is thus preferred:

Sample::CopyAsync().get();

It’s important to keep in mind that the get method will block the calling thread until the async method completes. As such, it is not appropriate to use the get method on a UI thread since it may cause the app to become unresponsive. An assertion will fire in unoptimized builds if you attempt to do so. The get method is ideal for console apps or background threads where you may not want to use a coroutine for whatever reason.

Once the async method completes, the get method will return any result directly to the caller. In the case of IAsyncAction and IAsyncActionWithProgress, the return type is void. That might be useful for an async method that initiates a file copy operation, but less so for something like an async method that reads the contents of a file. Let’s add another async method to our example:

struct Sample
{
    Sample() = delete;

    static Windows::Foundation::IAsyncAction CopyAsync();
    static Windows::Foundation::IAsyncOperation<hstring> ReadAsync();
};

In the case of ReadAsync, the get method will properly forward the hstring result to the caller once the operation completes:

Sample::CopyAsync().get();

hstring result = Sample::ReadAsync().get();

Assuming execution returns from the get method, the resulting string will hold whatever value was returned by the async method upon its successful completion. Execution may not return, for example, if an error occurred but we’ll talk more about error handling later.

The get method is limited in the sense that it cannot be used from a UI thread, nor does it exploit the full potential of the machine’s concurrency, since it holds the calling thread hostage until the async method completes. Using a coroutine allows the async method to complete without holding such a precious resource captive for some indeterminate amount of time.

Join me next time as we explore more about async in the Windows Runtime.

C++/WinRT: Working with Strings

I think it’s high time I restarted the series on C++/WinRT, providing short “how to” and “how it works” articles to help developers understand some of the fundamental principles of the C++ language projection for the Windows Runtime. As a recap, here’s what I covered thus far:

Consumption and Production

Working with Implementations

Fun with Agility

Optimizing Activation

Working with Namespaces

C++/WinRT in the Windows SDK

cppwinrt.exe in the Windows SDK

C++/WinRT now ships in the Windows SDK and the cppwinrt compiler is also available. Visual Studio 2017 even provides tentative support, so there’s a lot to talk about. The original Getting Started assumed that you had to get the C++/WinRT headers from GitHub. That’s no longer the case, so let’s get started again but this time with Visual Studio and go from there. This guide will assume that you have installed Visual Studio 2017 15.6 or later as well as the Windows SDK for RS4 or later. The 15.6 update of Visual Studio 2017 provides command line support for C++/WinRT. While the Window SDK will ensure that cppwinrt.exe is available from a developer command prompt, it’s Visual Studio that ensures that the headers are in the include path.

The C++ language has a bad reputation when it comes to strings. Unlike many other languages, C++ doesn’t have a built-in type representing a string of text. Rather, the C++ library fills that gap by providing std::string and its variants. Inevitably, std::string doesn’t work for everyone and thus we land up with a myriad of string types to contend with. C++17 attempts to alleviate some of this pain with the introduction of string conversion utilities and the loveable but contentious std::string_view class. Of course, if that were the end of the story it would certainly have a happy ending.

Sadly, std::string is just one option. There’s also std::wstring, largely for Windows developers where wchar_t dominates. The trouble is that wchar_t is 2 bytes on Windows and represents UTF-16 characters whereas wchar_t is typically 4 bytes on most other platforms and represents UTF-32 characters. Then there’s the more explicit std::u16string and std::u32string. And on it goes.

So what’s the solution? We need another string type! Seriously, the idea of a universal string type for C++ is unrealistic today. Perhaps one day we’ll get there. Until then, we have a partial solution and that is the std::string_view to bridge the gap between different libraries and their unique requirements. While C++/WinRT has its own string type, it provides convertibility with std::wstring_view specifically to address this problem.

C++/WinRT requires its own string type because while WinRT uses wchar_t characters, the ABI itself is not a subset of what either std::wstring or std::wstring_view provides and using those would lead to significant inefficiency. Instead, C++/WinRT provides the winrt::hstring that represents an immutable string consistent with the underlying HSTRING, but in such a way that C++ developers can largely ignore the specifics of WinRT string management and just work with what they know and love about C++. Consider the following example:

using namespace Windows::Networking::Connectivity;

int main()
{
    for (auto&& host : NetworkInformation::GetHostNames())
    {
        hstring name = host.DisplayName();

        printf("%ls\n", name.c_str());
    }
}

GetHostNames returns a collection of HostName objects representing the various network names associated with the computer. I can then call DisplayName to get a string representation. Since DisplayName is a WinRT API it naturally returns an hstring, but notice that I could just as easily have used auto:

auto name = host.DisplayName();

printf("%ls\n", name.c_str());

Suddenly, this looks very much like std::wstring. Indeed, there’s no reason to have a named local. I can more concisely express it as follows:

printf("%ls\n", host.DisplayName().c_str());

As you can see, it looks and feels like std::wstring and provides many of the same type aliases and functions. We could have changed the cppwinrt compiler to generate API strings using std::wstring directly, but that would have been inefficient. Still, we aim to make it as transparent as possible. You can for example, pass an hstring to a function expecting a std::wstring_view:

void print(std::wstring_view text);

int main()
{
    for (auto&& host : NetworkInformation::GetHostNames())
    {
        print(host.DisplayName());
    }
}

Notice that I’m not calling c_str or any other conversion helper. Since the hstring is convertible to std::wstring_view – and at no cost – this just works. It works the other way as well. I can create a HostName object directly, perhaps in anticipation of creating a socket connection:

using namespace Windows::Networking;

int main()
{
    HostName host(L"moderncpp.com");
}

While the HostHame constructor technically expects an hstring, it’s quite happy if you pass it a string literal. In fact, this is often more efficient than creating an hstring yourself. You might instead have a std::wstring or just a std::wstring_view and that will work just as well:

int main()
{
    std::wstring name = L"moderncpp.com";

    HostName host(name);
}

What about a std::wstring_view literal? No problem:

using namespace std::literals;

int main()
{
    HostName host(L"moderncpp.com"sv);
}

If you’re really curious, you’ll notice that all of the input parameters that should logically accept a winrt::hstring really expect a winrt::param::hstring. The param namespace has a set of types that are used exclusively for optimizing input parameters to naturally bind to STL types and avoid copies as well as other inefficiencies. You should never use those types directly, but that’s where the magic happens to make this work efficiently for input. Again, you should never use those param types yourself. Don’t use them as an optimization for your own functions – just use std::wstring_view.

The hstring also provides all of the comparison operators so that you can naturally and efficiently compare against its counterparts in the C++ standard library. It also includes everything you need to use hstring as a key for associative containers if need be. We also recognize that many C++ libraries use std::string and work exclusively with UTF-8 text. As a convenience, we provide helpers for converting back and forth as well:

hstring w = L"hello world";

std::string c = to_string(w);
assert(c == "hello world");

w = to_hstring(c);
assert(w == L"hello world");

As a team, we spend a lot of time focusing on performance. That includes machine instructions, but it also includes binary size. All of that comes into play when we talk about strings because of how heavily strings are used in the Windows Runtime. There are many other optimizations and affordances we provide for strings, but hopefully this gives you a good idea of how to make use of strings with C++/WinRT.

Variadic generators in C++

Coroutines allow us to write generators that yield values such that a function can effectively return multiple values. The coroutine return type can then provide begin and end functions and thus behave like an STL container or range expression. If you have Visual C++ handy, you can follow along using its simple experimental generator:

#include <experimental/generator>
using namespace std::experimental;

We can write a function that will produce a sequence of values as follows:

generator<int> get_values()
{
    co_yield 1;
    co_yield 2;
    co_yield 3;
}

From the caller’s perspective, it behaves much the same as if the get_values function had been written as follows:

std::vector<int> get_values()
{
    return { 1, 2, 3 };
}

The difference is that the coroutine does not require the container to be prepared in advance (or even allocated), but the caller can simply rely on the resulting range expression and write the same range-based for loop regardless:

int main()
{
    for (int value : get_values())
    {
        printf("%d\n", value);
    }
}

As you might expect, the results are staggering:

1
2
3
Press any key to continue . . .

But that’s not very interesting. Let’s imagine we have two (or more) containers with numbers as follows:

std::vector<int> a{ 1, 2, 3 };
std::vector<int> b{ 4, 5, 6 };

And we’d like to use the same simple range-based for loop to print out all their values:

for (int value : get_container_values(a, b))
{
    printf("%d\n", value);
}

How might we achieve that? With variadics of course. First we need to write a generalized get_values function that can effectively turn a parameter pack into a range:

template <typename First, typename ... Rest>
generator<First> get_values(First const& first, Rest const& ... rest)
{
    int ignored[] = { (co_yield first, 0), (co_yield rest, 0) ... }; ignored;
}

We need to separate out the first template argument from the parameter pack so that we can identify the type of the resulting generator. We then simply expand the function arguments and yield up each value in turn.

With this version of get_values, we can now write a more generalized version of the original example as follows:

for (int value : get_values(1, 2, 3))
{
    printf("%d\n", value);
}

No longer does the get_values function need to hardcode the values to yield to the caller and it works with types other than int. Using get_values as a building block, we can then write the get_container_values function that will iterate over its arguments and then iterate over each container’s values, yielding each in turn:

template <typename First, typename ... Rest, typename Value = First::value_type>
generator<Value> get_container_values(First const& first, Rest const& ... rest)
{
    for (First const& current : get_values(first, rest ...))
    {
        for (Value const& value : current)
        {
            co_yield value;
        }
    }
}

Again, the first template argument must be separated to determine the type of the resulting generator. The get_values function is used to produce a range from the get_container_values arguments. Could this be implemented without coroutines? Sure, but not nearly as simply and most likely involving copies of containers and elements. The get_container_values function will not make a copy of a single element.

We can now write the following simple program:

int main()
{
    std::vector<int> a{ 1, 2, 3 };
    std::vector<int> b{ 4, 5, 6 };

    for (int value : get_container_values(a, b))
    {
        printf("%d\n", value);
    }
}

The results are beautifully simple:

1
2
3
4
5
6
Press any key to continue . . .

C++/WinRT: Working with Namespaces

Previous: Optimizing Activation

The Windows Runtime adopted namespaces as part of its type system. This works rather well since most languages targeting the Windows Runtime support namespaces in a fairly uniform way. Unfortunately, C++ has a bit more history than most languages and that is certainly true when it comes to the Windows platform. The problem is that C++/WinRT was not the first language projection for C++. C++/CX may not have been standard C++, but it exists within the Visual C++ compiler such that it causes problems when porting a project from C++/CX to C++/WinRT and especially when gradually migrating from one to the other. Then there’s the Windows SDK with its own historical complications.

Fortunately, C++/WinRT was designed with all of this in mind. The Windows SDK ships with headers describing the Windows Runtime APIs in standard C++. This is known as an ABI rather than a language projection since its really just a bunch of COM interface declarations and no attempt is made to “project” it into modern C++. I might use the IStringable type as follows:

#include <windows.foundation.h>
using namespace ABI::Windows::Foundation;

IStringable * stringable = ...

HSTRING value = nullptr;
HRESULT hr = stringable->ToString(&value);

Naturally you might want to use smart pointers and handle wrappers here, but that’s not part of the ABI. Notice that the windows.foundation.h header introduces a root ABI namespace in which the “Windows.Foundation.IStringable” type is declared. This is a good thing for the SDK to do. Technically, it’s the MIDL compiler that prepends this lovely disambiguator. C++/WinRT takes much the same approach to namespaces:

#include <winrt/windows.foundation.h>
using namespace winrt::Windows::Foundation;

IStringable stringable = ...

winrt::hstring value = stringable.ToString();

Notice that instead of the ABI root namespace, I’m now using the winrt root namespace. The Windows namespace, or any other namespace found in a Windows Metadata (.winmd) file, will be safely nested within the respective root namespaces. This is significant because it means that you can use the two together in the same project. There’s a way to disambiguate type names.

And then comes C++/CX and it blissfully thinks it lives on an island all on its own:

using namespace Windows::Foundation;

IStringable ^ stringable = ...

Platform::String ^ value = stringable->ToString();

Notice that there’s no root namespace clearly identifying this “Windows” from any other. Here “Windows” is the root namespace. That’s a bit of a drag. There are also various culprits in the Windows SDK, headers that inexplicably chose not to use the ABI root namespace. What to do?

All is not lost. Naturally, if you’re starting a new project then you can just ignore the ABI from the Windows SDK and you can just avoid C++/CX entirely:

using namespace winrt;
using namespace Windows::Foundation;

IStringable stringable = ...

hstring value = stringable.ToString();

Here I start with a using directive, allowing unqualified name lookup for anything in the winrt namespace. This is the simplest and most convenient route. You might still need to include the ABI headers from the Windows SDK. Perhaps to access an interop API not described in Windows metadata. But you must be explicit about it. Simply adding a using directive will not work:

using namespace winrt;
using namespace Windows::Foundation;
using namespace ABI::Windows::Foundation; // error!

The compiler will tell you that the ABI namespace is ambiguous. That’s because the winrt namespace itself includes its own ABI representation in the winrt::ABI namespace. You might try to be explicit as follows:

using namespace winrt;
using namespace Windows::Foundation;
using namespace ::ABI::Windows::Foundation;

IStringable stringable = ... // error!

But that won’t work either. Now the IStringable type name is ambiguous since that name could refer to either winrt::Windows::Foundation::IStringable or ABI::Windows::Foundation::IStringable.

The same problem occurs when mixing C++/CX with C++/WinRT or the Windows SDK for that matter. This is certainly not a problem that C++/WinRT introduced. One solution is just to be explicit:

winrt::Windows::Foundation::IStringable stringable = ...

While that works, it’s far from convenient. Another solution is to create namespace aliases for the different islands and use those instead:

namespace cx
{
    using namespace ::Windows::Foundation;
}

namespace sdk
{
    using namespace ::ABI::Windows::Foundation;
}

namespace winrt
{
    using namespace Windows::Foundation;
}

I can now unambiguously refer to the IStringable representation from all three type systems in a single program quite conveniently:

int main()
{
    cx::IStringable ^ hat = ...
    sdk::IStringable * pointer = ...
    winrt::IStringable value = ...
}

Any additional namespaces can easily be added as required:

namespace winrt
{
    using namespace Windows::Foundation;
    using namespace Windows::Web::Syndication;
}

Again, this is only required for backward compatibility and in a few other relatively rare cases where you might need to interop between these disparate manifestations of the Windows Runtime APIs.

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.

C++/WinRT: Optimizing Activation

Previous: Fun with Agility

Activation and agility have a strange relationship. In the last installment, I talked about agility, but agility also has an impact on activation. When I talk about activation I mean those things that the language projection (any language projection) must do in order to interact with runtime classes. This might be calling some constructor like this:

using namespace Windows::UI::Xaml::Media;

FontFamily font(L"Consolas");

Or it might be calling some static method like this:

using namespace Windows::UI::Xaml;

Window window = Window::Current();

In either case, activation is at play. That’s because in both cases, the activation factory for the runtime class must be retrieved. In the first example, the “Windows.UI.Xaml.Media.FontFamily” activation factory is what actually creates the FontFamily object under the hood. In the second example, it is the “Windows.UI.Xaml.Window” activation factory that actually implements the “Current” property.

Optimizing activation is all about making the retrieval of the activation factory as efficient as possible. James and I talked about how this is done in this presentation at CppCon 2016. The gist of it is that if the activation factory is agile then it can simply be cached via a magic static. Of course, if the activation factory is not agile then it would not be safe to do so since that would allow the factory object to be accessed from a different apartment to the one in which it was created.

Activation factories should be agile, but sadly some are not. Caching agile activation factories is safe since the cached pointer may be used by any thread from any apartment. Non-agile activation factories may only be used by threads from the same apartment and the overhead of managing a per-apartment cache is prohibitive. Non-agile activation factories are also the source of a variety of bugs. We are moving to a world where all activation factories will be agile. This is the most reliable and efficient model, but we need this fallback in C++/WinRT to deal with existing non-agile factories.

One of the nice things about C++/WinRT is that it is a header-only library. That means you can step into those constructors and static methods above and see how they map to the underlying WinRT plumbing. In both cases, you’ll see that they eventually call this function:

template <typename Class, typename Interface = Windows::Foundation::IActivationFactory>
Interface get_activation_factory()
{
    static Interface factory = impl::get_agile_activation_factory<Class, Interface>();

    if (!factory)
    {
        return impl::get_activation_factory<Class, Interface>();
    }

    return factory;
}

How this function is implemented is an implementation detail but you can clearly see what’s going on. The internal get_agile_activation_factory function will only return a valid factory object if the factory implements the IAgileObject interface. This check is done on demand and once per process. Due to the proliferation of required interfaces and static members in the Windows Runtime, the ability to optimize activation factory access is vital in building high-performance apps and components. As we illustrated at CppCon, the approach taken by C++/WinRT performs substantially better than C++/CX. I have also successfully campaigned within Microsoft to have all activation factories eventually becoming agile. This will provide significant performance wins for both existing and new apps targeting the Windows platform. The good news is that there’s nothing you need to do to opt in to this performance. C++/WinRT will give you the best possible performance today and your apps will only get faster as more of the Windows Runtime switches to agile activation factories.

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 Namespaces