C++/WinRT at CppCon

I hope you’re on your way to CppCon this week where we’re introducing C++/WinRT, the future of Modern C++ for the Windows Runtime!

Please join us on Monday as James McNellis and Kenny Kerr introduce C++/WinRT at 11am and show you what standard C++ can do for the Windows platform.

Also, be sure to join us for CoroutineCon on Tuesday as Gor Nishanov, James and Kenny spend the day focused on C++ coroutines, from introduction, internals, and finally real-world application with C++/WinRT.

Bring your questions. We hope to see you there!

Microsoft + Modern

As I mentioned in October, I have joined Microsoft and specifically the Windows team to work on the future of standard C++ for Windows. What does this mean for the Modern project? Modern C++ for the Windows Runtime is now owned by Microsoft. That means I won’t be releasing any further updates here or on GitHub. Instead, you should expect a future version to arrive directly from Microsoft. The good news is that I am finally free to work on Modern in a fulltime capacity so I will be able to deliver a production quality language projection far more rapidly than I could have on my own. I also have the help of an incredible team of people here at Microsoft, which means that Modern will be so much better than I could have imagined!

Available on GitHub

Modern is now available for download from GitHub. This is the first public preview of the Modern project and I look forward to your feedback!

Here it is: https://github.com/kennykerr/modern

Credits

I would like to thank the developers who tested private builds or contributed in one way or another including James Clarke, Ales Holecek, James McNellis, Jeremiah Morrill, Larry Osterman, Raffaele Rialdi, John Sheehan, Kirk Shoop, and Charles Torre. Your feedback helped to shape my understanding of the Windows Runtime and the modern C++ language projection.

What is Modern?

Modern is a Standard C++ language projection for the Windows Runtime. The Modern compiler produces a header-only library designed to provide Standard C++ developers with first-class access to the Windows API. As I’ve previously shown, Modern provides a classy type system to target the Windows platform with standard C++.

Need a simple example? The Windows.Foundation namespace provides the Uri class with its constructor accepting a string argument. The C++ developer can call this in the most natural way:

using namespace Windows::Foundation;

Uri first(L"http://kennykerr.ca/");

The Uri class also provides the CombineUri method, which returns another Uri object:

Uri combined = first.CombineUri(L"articles");

And it provides a way to get the canonical representation as a string:

String string = combined.ToString();

That’s all there is to it. No pointers or hats, no reference counting or error codes, nothing that isn’t straightforward and natural to the casual C++ developer.

But I need more power!

Sure thing. Modern provides a library-based language projection. That means you can drill down as far as you want to go. Creating a Windows Runtime class involves the use of an activation factory.

auto factory = GetActivationFactory<Uri, IUriRuntimeClassFactory>();

If you’ve ever tried calling the operating system’s RoGetActivationFactory function you’ll know what a saving this is. With the factory in hand, I can call the logical construction method to create the Uri object:

Uri uri = factory.CreateUri(L"http://kennykerr.ca/");

Not satisfied with the Uri class? You can just ask for Uri’s default interface:

IUriRuntimeClass default = uri;

But if you do that, you’ll notice that IUriRuntimeClass doesn’t provide the ToString method. This comes courtesy of the IStringable interface also provided by the Uri class. No problem, we can just query for it:

IStringable stringable = default.As<IStringable>();	
String string = stringable.ToString();

The Windows Runtime is built on the essentials of COM. That means IUnknown** and lots of HRESULTs, right? Wrong. Modern takes advantage of C++11 and beyond to provide a truly modern language projection for the Windows Runtime. So while it is still COM under the hood, a C++ developer should think in terms of references rather than pointers. Practically nothing is off limits to the developer hungry for power, but you don’t need to sacrifice productivity or safety along the way. About the only thing that Modern prohibits is explicit reference counting. It uses C++11’s move semantics to handle reference counting reliably and sparingly. So, given an IUnknown reference:

IUnknown unknown = uri;

I can call the modern equivalent of IUnknown’s QueryInterface:

IUriRuntimeClass uri = unknown.As<IUriRuntimeClass>();	

But there’s no AddRef or Release methods. You can even retrieve the underlying interface pointer and call QueryInterface directly:

IUriRuntimeClass uri;
HRESULT hr = unknown->QueryInterface(set(uri));

But even here the reference counting is hidden away. The uri object receiving the new reference takes care of its own reference counting and the AddRef and Release virtual functions are still inaccessible. So while all of the underlying ABI virtual functions are just a -> away, the reference counting is safely and efficiently taken care of by the library and the compiler.

What if you still desperately need to shoot yourself in the foot? No problem, just get the naked COM interface pointer:

ABI::Windows::Foundation::IUriRuntimeClass * danger = get(uri);
danger->AddRef();

The rabbit hole goes deeper still but I’ll leave it there for the moment.

What’s ready?

The GitHub repository includes library sets for developing apps for Windows 8.1 and Windows 10. It includes full projections containing everything you might need to build anything you can imagine, but it also contains smaller library sets for scenarios where you might not need XAML or just want to use the Windows Runtime from a desktop app, console, or service.

You can use this public preview to build XAML apps or apps directly with CoreWindow. You can write console and desktop apps that just happen to use Windows Runtime components but don’t rely on an app container or core dispatcher. It’s up to you.

What’s next?

I am not releasing the Modern compiler at this time. The compiler is required for component development, to produce updated library sets, as well as project templates.

Support for binary composition, required by XAML, is currently experimental. This is likely where I’ll be spending a lot more time improving the language projection. You can however write a simple XAML app and take advantage of the existing support for binary composition. An example is provided on GitHub.

XAML also requires a limited form of reflection. This is mostly working but it needs a bit more time to mature and I need to figure out how XAML designer support can be integrated.

Support for creating collections is in the process of being rewritten and I’ll be including that in an upcoming drop. You can of course consume collections produced by the Windows API, but you cannot create your own collections very easily. Expect this in the next update.

Windows Runtime structures are currently projected quite sparsely. In particular, better support for Numerics is coming.

Clang support is experimental. The current Clang build for Windows doesn’t work too well with the RTM build of Visual Studio 2015. Debugging is not integrated and there is a mismatch between the Clang and CL compiler options.

Visual Studio and the IntelliSense engine still struggles a bit with the large headers and a lot of the metaprogramming, but the compiler is satisfied and that’s what counts. This is the reason why the Modern library is spread out across a number of headers rather than just shipping in a single header file. I’ve done a lot of work to simplify the code. Earlier builds of the language projection took a few minutes to precompile. The code was beautiful with elegant templates but compile time was a killer. I’m actively working on reducing precompile time, but it is already quite reasonable.

Finally, I was hoping to secure some kind of corporate sponsorship for the Modern project but that has not materialized. This means that I’ll be updating Modern as I have free time to commit to the project.

Enjoy!

Clang and the Windows Runtime

A compiler developer recently challenged me to see whether Modern produces code that Clang can compile. The Modern compiler produces a C++ library that is effectively a standard C++ language projection for the Windows Runtime. Given that it is standard C++, surely the Clang compiler will be able to handle it. As you can imagine, a compile-time language projection is going to rely quite heavily on generic programming so it took about an hour this morning to tweak the base library to support the particular way that Clang interprets the C++ standard. It was mostly a bunch of warnings about missing typename keywords in template type parameters. A short while later I built the first app targeting the Windows Runtime with Modern C++ and the Clang compiler.

clang

Universal Windows Apps with Standard C++

This demo shows you how Modern C++ for the Windows Runtime makes it easy to write apps for the new Universal Windows Platform with Standard C++.

It features a framework-less app using the new Windows Composition API. This API is still evolving and I plan to have a course available once it has been finalized. This is just a quick tour of what you can expect.

Now isn’t this the way you’d like to write apps for Windows?

By the way, in the demo I included “windows.applicationmodel.core windows.ui.composition” on the command line and yet I was able to reference Windows::Graphics in my app. How is that possible?

The Modern compiler automatically works out dependencies and includes them in the resulting library to ensure that all references are present. If you include the –depends option it will actually trace this out for you. Here’s what that looks like. Thanks to John Sheehan for raising this question.

C:\temp>modern library -include windows.applicationmodel.core windows.ui.composition -depends

Modern v1.22 - http://moderncpp.com
Modern C++ for the Windows Runtime
Copyright (c) 2015 Kenny Kerr

Reading...
 windows.applicationmodel.core
  windows.foundation
  windows.applicationmodel
   windows.storage
    windows.storage.fileproperties
     windows.devices.geolocation
     windows.storage.streams
    windows.storage.provider
    windows.storage.search
     windows.data.text
    windows.system
     windows.gaming.input
     windows.ui.popups
     windows.ui.viewmanagement
      windows.devices.enumeration
       windows.applicationmodel.background
        windows.applicationmodel.calls.background
        windows.devices.bluetooth
         windows.devices.bluetooth.genericattributeprofile
         windows.devices.bluetooth.rfcomm
          windows.networking
           windows.networking.connectivity
          windows.networking.sockets
           windows.security.credentials
           windows.security.cryptography.certificates
           windows.web
        windows.devices.bluetooth.advertisement
        windows.devices.bluetooth.background
        windows.devices.sensors
         windows.graphics.display
        windows.devices.sms
       windows.ui
      windows.ui.core
       windows.ui.input
        windows.devices.input
       windows.ui.input.inking
        windows.foundation.numerics
       windows.ui.input.inking.core
  windows.applicationmodel.activation
   windows.applicationmodel.appointments.appointmentsprovider
    windows.applicationmodel.appointments
   windows.applicationmodel.calls
    windows.applicationmodel.contacts
   windows.applicationmodel.contacts.provider
   windows.applicationmodel.datatransfer.sharetarget
    windows.applicationmodel.datatransfer
     windows.security.enterprisedata
   windows.applicationmodel.search
   windows.devices.printers.extensions
   windows.media.speechrecognition
    windows.globalization
   windows.security.authentication.web.provider
    windows.security.authentication.web
    windows.security.authentication.web.core
    windows.security.cryptography.core
    windows.web.http
     windows.web.http.filters
     windows.web.http.headers
   windows.storage.pickers.provider
 windows.ui.composition
  windows.graphics.directx.direct3d11
   windows.graphics.directx
  windows.graphics.effects
Projecting...
Writing...

When Standard C++ Isn’t Enough

Last time I showed how Standard C++ lets you go beyond the compiler. Modern C++ offers the productivity of C# and performance that beats even C++/CX. Well if Standard C++ is so great, why isn’t anyone using it to write Windows apps with the Windows Runtime? Because Standard C++ is not enough.

Think about this. The Windows SDK for Windows 8.1 – counting only the Windows Runtime – includes about 2,450 interfaces amounting to around 10,880 methods. Windows 10 – as of build 10069 – is over 3,930 interfaces and 17,748 methods. It is naïve to think that C++ developers are going to use the ABI interfaces directly since they are tedious to use and were never intended to be used directly. It is further unrealistic to think that C++ developers are going to “wrap” those native interfaces with modern C++ classes to create useful libraries. All of the supposed productivity is lost when you have to spend countless hours first writing a library. I tried that before. Here’s another C# example:

CurrencyFormatter currency = new CurrencyFormatter("USD");
currency.ApplyRoundingForCurrency(RoundingAlgorithm.RoundDown);

String result = currency.Format(123.456);
Debug.Assert(result == "$123.45");

I’ve created a currency formatter, set the rounding algorithm, and formatted a value. What about Standard C++? A lot of developers seem to think that C# is the most popular language on the Windows platform today because it is so much better than C++. It’s not, instead it’s all about the tooling. One of the main arguments for .NET was that it avoided the reference counting hell that C++ apparently produced. Proponents of this position would like to show you the example above written in Standard C++:

HSTRING_HEADER header = {};
HSTRING string = nullptr;
WindowsCreateStringReference(L"Windows.Globalization.NumberFormatting.CurrencyFormatter", 56, &header, &string);
ICurrencyFormatterFactory * factory = nullptr;
RoGetActivationFactory(string, __uuidof(factory), reinterpret_cast<void **>(&factory));

WindowsCreateStringReference(L"USD", 3, &header, &string);
ICurrencyFormatter * currency = nullptr;
factory->CreateCurrencyFormatterCode(string, &currency);
factory->Release();

ICurrencyFormatter2 * currency2 = nullptr;
currency->QueryInterface(&currency2);
currency2->ApplyRoundingForCurrency(RoundingAlgorithm_RoundDown);
currency2->Release();

INumberFormatter * formatter = nullptr;
currency->QueryInterface(&formatter);
currency->Release();

HSTRING result = nullptr;
formatter->FormatDouble(123.456, &result);
formatter->Release();

assert(wcscmp(WindowsGetStringRawBuffer(result, nullptr), L"$123.45") == 0);
WindowsDeleteString(result);

But no C++ developer in his right mind would ever write code like this (and I haven’t even included error handling). Instead the C++ developer would naturally write something like this:

CurrencyFormatter currency(L"USD");
currency.ApplyRoundingForCurrency(RoundingAlgorithm::RoundDown);

String result = currency.Format(123.456);
assert(result == L"$123.45");

There are no pointers and no reference counting that you can see. The compiler takes care of these details and in fact does so more reliably and more efficiently than the C# compiler is able to do since this code is inherently deterministic. While Microsoft claims that C++ has always been supported this is not entirely truthful. You can read more about C++ vs C++/CX here.

The problem is that Standard C++ is not enough. Good tooling is required. C# developers don’t use the C# compiler in isolation but download the 4GB Visual Studio tools. C++ developers need better tools in order to write apps and components for the Windows platform. Modern C++ for the Windows Runtime provides that tool. Modern works in conjunction with Visual C++ to provide a first-class developer experience for C++.

currency

Why shouldn’t C++ developers get a classy type system with all the same productivity and unparalleled performance? Here’s how it works: the Modern compiler generates a complete language projection for Standard C++.

modern

I can simply run “modern.exe library” and it will produce a language projection for the latest version of the Windows SDK that is locally installed. There are options to use an alternative SDK, only include certain namespaces (to produce a smaller library), and so on.

library

The result is a header-only library that I can include with a single line of code:

#include <modern.h>

This header is backed by a small set of headers mainly because the Visual Studio editor would choke on one large file.

headers

The base.h header is the language projection itself. This contains all of the generic or metaprogramming that describes the bindings between modern C++ and the underlying ABI in such a way that the C++ compiler can chew on it at compile time. The sdk.* headers are essentially the metadata describing the various Windows API classes and other types that form the public surface area for the Windows API. While base.h is handcrafted, the sdk.* headers are entirely generated based on the Windows SDK.

The Modern library is also not simply a class library. It provides all of the building blocks you might need to drill in or tweak the performance of your app. You might normally be satisfied with the productivity of creating a CurrencyFormatter object as follows:

CurrencyFormatter currency(L"USD");

At other times you might want to create the activation factory yourself. The Modern library has got you covered:

auto factory = GetActivationFactory<CurrencyFormatter, ICurrencyFormatterFactory>();

You can then create a CurrencyFormatter object at your convenience:

CurrencyFormatter currency = factory.CreateCurrencyFormatterCode(L"USD");

This is obviously still far more convenient and reliable than using the ABI provided by the Windows SDK for C++ developers. There’s no reference counting, string handles, or pointers.

And then there’s formatting a currency value:

String result = currency.Format(123.456);

You might want to avoid an exception here perhaps to deal with any failures directly. No problem, Format is actually a method called FormatDouble on the INumberFormatter interface:

INumberFormatter formatter = currency;

String result;
HRESULT hr = formatter->abi_FormatDouble(123.456, set(result));

assert(hr == S_OK);
assert(result == L"$123.45");

As you can see you have all the control you might need, all of the productivity and safety you would expect, and all from your favorite C++ compiler thanks to Modern C++ for the Windows Runtime. Now what about C++? (19m3s)🙂