Author Archives: Kenny Kerr

First major update for 2017

While we haven’t made many public announcements since CppCon 2016, we have been hard at work on the next major update to C++/WinRT and in anticipation of releasing the cppwinrt.exe compiler to the public. Today’s update on GitHub is the result of months of hard work from our small team. It’s also an early look at what you’ll soon get directly from the Windows SDK.

https://github.com/microsoft/cppwinrt

What’s new

C++17

This update takes advantage of many improvements in C++17 to simplify and improve the quality of the library. These are only possible thanks to much hard work on the part of the Visual C++ team and delivered in the Visual Studio 2017 15.3 release. These include:

  • Simpler static_assert
  • Nested namespace definitions
  • constexpr functions
  • if constexpr
  • optional
  • string_view
  • __has_include
  • Logical operator traits

Coroutines

The base library has been updated to reflect the latest coroutine draft standard as we continue to track the progress of this new language feature.

Clang

While Visual C++ continues to be our primary target, we use Clang as our secondary compiler to ensure standard conformance. Many small changes have been made in this update to support Clang builds and to fix correctness bugs that were only found with Clang builds.

Support for [[deprecated]]

The C++/WinRT language projection now reports on any deprecated Windows APIs via the standard [[deprecated]] attribute. For example, the following code will produce a C++ compiler error:

using namespace Windows::Storage::Pickers;

FileOpenPicker::ResumePickSingleFileAsync();

error C4996: ‘winrt::Windows::Storage::Pickers::FileOpenPicker::ResumePickSingleFileAsync’: Instead, use PickSingleFileAsync

Arguably, this should be a warning, but the Visual C++ compiler currently treats it as an error.

Improved support for WinRT error origination, propagation, chaining, and extensibility

This is largely an improvement to enable the Windows Runtime to produce more coherent crash dumps for postmortem debugging, but a few small changes inside the C++/WinRT exception type – winrt::hresult_error – have also been made to provide improved error messages during live debugging. The debugger team has also done work to make it easier to debug errors that occur in a brokered process.

Improved code gen (fewer instructions) and build throughput

The C++/WinRT compiler now produces considerably smaller headers by omitting a lot of type information from internal type projections that weren’t adding any value and were only causing the C++ compiler to do more work unnecessarily. In addition, the code we generate for a few input parameter bindings now results in noticeably fewer CPU instructions, resulting in small binaries. This includes high-traffic types such as strings and collections.

Support for compile-time generic GUID calculation

This is one of the biggest improvements in this update. Previously, any generic interface that was not defined in metadata lacked a specialization informing the projection of the GUID for that particular interface specialization. For example:

using namespace Windows::Foundation::Collections;

IMap<hstring, float> map;

If you happened to use the map and the compiler could not find an appropriate specialization providing the GUID, a cryptic compiler error was produced. Even if you could recognize the problem, determining the correct GUID to assign to the specialization was non-trivial and largely undocumented. This update now codifies the algorithm for determining the GUID for arbitrary specializations purely in constexpr functions that C++/WinRT uses internally to compute GUIDs at compile-time as needed. This solves what is likely our top usability concern with C++/WinRT. It also provides a great stress test for the compiler. 🙂

Many thanks to Harry Pierson for building the first Clang prototype and proving that it could be done!

Simplified ABI interop

As we’ve improved the quality and maturity of the projection, we’ve also reduced the need for a developer to access the ABI. As such, the ABI generated by the C++/WinRT compiler is no longer something that we would like you to use. There simply isn’t any good reason for that and it allows us to optimize it for our own internal use to give you the fastest possible builds.

While the C++/WinRT language projection is designed to provide no-compromise access to the modern Windows API, we recognize that there are instances where you need to interop with other libraries or tools that may not support C++/WinRT directly. The base library (winrt/base.h) provides a set of helper functions that assist in converting between C++/WinRT types and their equivalents in other language projections such as C++/CX or the Windows SDK headers produced by the MIDL compiler. Although we don’t directly support interop with other language projections, to avoid cross-dependencies, you can use the following helper functions to streamline the process as you migrate your code to C++/WinRT.

The following helper function may be used to convert a C++/WinRT object to
an equivalent C++/CX object:

template <typename T>
T^ to_cx(winrt::Windows::Foundation::IUnknown const& from)
{
    return safe_cast<T^>(reinterpret_cast<Platform::Object^>(winrt::get_abi(from)));
}

This function uses the winrt::get_abi function to retrieve the source
object’s underlying IUnknown pointer and then casts this to a C++/CX
object before using the C++/CX safe_cast extension to query for the
requested C++/CX type.

The following helper function may be used to convert a C++/CX object to
an equivalent C++/WinRT object:

template <typename T>
T from_cx(Platform::Object^ from)
{
    T to{ nullptr };

    winrt::check_hresult(reinterpret_cast<::IUnknown*>(from)
        ->QueryInterface(winrt::guid_of<T>(),
                         reinterpret_cast<void**>(winrt::put_abi(to))));

    return to;
}

This function casts the C++/CX object to retrieve the source object’s
underlying IUnknown pointer and then calls QueryInterface (the ABI
equivalent of the C++/CX safe_cast extension) to query for the requested
C++/WinRT type.

The following helper function may be used to convert an interface pointer
defined by the Windows SDK headers produced by the MIDL compiler to an
equivalent C++/WinRT object:

template <typename T>
T from_abi(::IUnknown* from)
{
    T to{ nullptr };

    winrt::check_hresult(from->QueryInterface(winrt::guid_of<T>(),
                                              reinterpret_cast<void**>(winrt::put_abi(to))));

    return to;
}

This function simply calls QueryInterface to query for the requested
C++/WinRT type.

A helper function is not required to convert from a C++/WinRT object to the
equivalent interface pointer defined by the Windows SDK headers produced by
the MIDL compiler. Simply use the as member function to query for the
requested interface. It will return a winrt::com_ptr object wrapping the
requested ABI type.

Simplified and more intuitive parameter binding for strings and collections

Strings, arrays, and collections all present unique challenges to any language projection. C++/WinRT is unique in that it provides blazingly fast performance for all three, avoiding copies, and minimizing machine instructions at call sites. We also provide natural conversion support for std::wstring_view and most C++ standard library containers without introducing copies.

Removal of implementation details from winrt namespace

We have steadily cleaned up the base library to avoid leaking any unnecessary implementation details. The winrt namespace is now a lot leaner, exposing only those functions and types that you could conceivably need to use in order to make the most of C++/WinRT. Anything that begins with impl_ or is within the winrt::impl namespace should be considered an implementation detail subject to change at any time. We do not consider it a breaking change to rename or remove an implementation detail and that includes the use of the internal ABI used by C++/WinRT.

As soon as the Visual C++ compiler resolves a few more bugs, we plan to provide C++/WinRT as a C++ module. At that point, all of these implementation details will physically be unavailable as they will not be epxorted by the C++/WinRT module.

Automatic object identity and hashing support

We now provide intelligent object identy and hashing support for all C++/WinRT types so that you can easily use them as keys in standard containers like std::map and std::unordered_map.

Optimized agility implementation

C++/WinRT favors agile object implementations and so should you. We make it very simple to create agile objects and also provide the leanest possible implementation, reducing the overhead of (automatically) implementing IAgileObject and IMarshal to the point where instances of C++/WinRT types are considerably smaller than their WRL and C++/CX counterparts.

Optimized delegate implementation

WinRT delegates are likewise optimized for space so that they may be safely used as ABI-portable callbacks without much concern for their overhead.

Support for derived classes and binary composability in winrt::implements

The implements class template remains at the heart of much of the C++/WinRT language projection when it comes to authoring types. It has received many improvements to make it easier to implement complex WinRT types and particularly in support for composable types, such as those required by the Windows.UI APIs.

Default implementation of GetRuntimeClassName

You may notice that objects created with winrt::implements now provide a default implementation of GetRuntimeClassName that returns the metadata name for the first interface being implemented. In many cases, this is sufficient to support the runtime, but you can of course override this with your own class names as necessary.

Support for disabling factory caching

C++/WinRT provides the fastest factory caching of any language projection. However, due to the unfortunate relationship between COM statics, the CRT, and the OS loader it is entirely possible that those statics are not torn down correctly when C++/WinRT is used within a DLL. We now provide an option to disable caching in those cases. We are also investigating how we might finally solve the problem of COM statics once and for all.

Experimental natvis support

The experimental natvis support makes it easier to interrogate C++/WinRT types from within a debugger.

Those are just a few highlights for now. We have worked hard to build a world-class language projection for the systems programmer and the app developer alike. Our goal is to enable C++ developers to write beautiful high-performance apps and components with incredible ease.

What’s next

In the coming weeks, we will release an insider build of the Windows SDK that will include both the C++/WinRT headers, targeting that particular build of the SDK, as well as the C++/WinRT compiler itself. You will be able to simply include the headers into any C++ project without having to worry about downloading the right set of headers from GitHub or worrying about include paths. Not only that, but you’ll be able to use the cppwinrt.exe compiler to generate your own projections and even create your own WinRT components with the same standard C++ that we all love.

Following the Windows SDK release, we plan to provide XAML compiler support and then C++/WinRT project support within Visual Studio.

Longer term, I’m working with the Visual C++ team to support the future of C++ including C++ modules, reflection, code synthesis, and metaclasses. It’s an exciting time to be a C++ developer on the Windows platform!

Credits

I would like to thank the team responsible for C++/WinRT this year: Scott Jones, Ryan Shepherd, Kevin Welton, Brent Rector, and Ben Kuhn. As always, I am indebted to the Visual C++ team for their incredible support. You can get a glimpse inside my relationship with the C++ team here from Andrew Pardoe’s comments here.

Kenny Kerr

C++/WinRT Available on GitHub

I’m happy to announce that C++/WinRT is now available on GitHub. C++/WinRT is the future of the Modern project and the first public preview coming officially from Microsoft.

https://github.com/microsoft/cppwinrt

What’s new

Since the first public preview a little over a year ago we’ve made a big investment in the C++/WinRT base library. This update also targets build 14393 of the Windows SDK, providing access to all of the Windows 10 Anniversary Update (Version 1607) features.
Significant improvements have been made to virtually all parts of the base library including the metaprogramming facilities, string and error handling. We’ve also added support for various missing features include arrays, collections, and weak references. Delegates are now more efficient and it’s possible to implement any WinRT interface within the projection. This update also includes our complete async programming model based on coroutines.

What’s next

We’re now switching gears to focus on Xaml and component support among other things. Please give it a try and let us know what you think!

For more information, please watch our CppCon talks on YouTube:

Embracing Standard C++ for the Windows Runtime (Slides)

Putting Coroutines to Work with the Windows Runtime (Slides)

Credits

I would like to thank the team responsible for C++/WinRT over the last year: Josue Noriega de la Vega, Kevin Welton, Brent Rector, Jerry Dunietz, Peter Torr and Ben Kuhn. I would also like to thank the Visual C++ team for their help in making this possible. It could not have happened without the help of folks like James McNellis, Gor Nishanov, Vinny Romano, Victor Tong, Jim Radigan, Cody Miller, Harry Pierson, and many others.

CppCon Videos

The videos for our CppCon talks are now available online. The first talk introduces the C++/WinRT language projection and the second discusses how we integrated coroutines to produce a very natural and efficient async programming model.

Embracing Standard C++ for the Windows Runtime (Slides)

Putting Coroutines to Work with the Windows Runtime (Slides)

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!