Microsoft has just announced the release of Windows 10 SDK Preview Build 17709. Along with the usual API changes, this version comes with some updates and fixes for C++/WinRT. Here’s what you need to know before trying out the SDK on your machine.
- This update introduces many improvements and fixes for C++/WinRT. Notably, it introduces the ability to build C++/WinRT without any dependency on the Windows SDK. This isn’t particularly interesting to the OS developer, but even in the OS repo it provides benefits because it does not itself include any Windows headers. Thus, a developer will typically pull in fewer or no dependencies inadvertently. This also means a dramatic reduction in the number of macros that a C++/WinRT developer must guard against. Removing the dependency on the Windows headers means that C++/WinRT is more portable and standards compliant and furthers our efforts to make it a cross-compiler and cross-platform library. It also means that the C++/WinRT headers will never be mangled by macros. If you previously relied on C++/WinRT to include various Windows headers, you will now have to include them yourself. It has always been good practice to include any headers you depend on explicitly, and not rely on another library to include them for you.
- Support get_strong and get_weak to create delegates: This update allows a developer to use either get_strong or get_weak instead of a raw this pointer when creating a delegate pointing to a member function.
- Add async cancellation callback: The most frequently requested feature for C++/WinRT’s coroutine support has been the addition of a cancellation callback.
- Simplify the use of APIs expecting IBuffer parameters: This update provides direct access to the data behind an IBuffer implementation using the same data naming convention used by the C++ standard library containers.
- Conformance: Improved support for Clang and Visual C++’s stricter conformance modes.
- Improved code gen: Various improvements to reduce code size, improve inlining, and optimize factory caching.
- Remove unnecessary recursion: When the command line refers to a folder rather than a specific winmd, cppwinrt will no longer search recursively for winmd files. It causes performance problems in the OS build and can lead to usage errors that are hard to diagnose when developers inadvertently cause cppwinrt to consume more winmds than expected. The cppwinrt compiler also now handles duplicates more intelligently, making it more resilient to user error and poorly-formed winmd files.
- Declare both WINRT_CanUnloadNow and WINRT_GetActivationFactory in base.h: Callers don’t need to declare them directly. Their signatures have also changed, amounting to a breaking change. The declarations alleviate most of the pain of this change. The change is necessitated by the fact that C++/WinRT no longer depends on the Windows headers and this change removes the dependency on the types from the Windows headers.
- Harden smart pointers: The event revokers didn’t revoke when move-assigned a new value. This lead me to take a closer look at the smart pointer classes and I noticed that they were not reliably handling self-assignment. This is rooted in the com_ptr class template that most of the others rely on. I fixed com_ptr and updated the event revokers to handle move semantics correctly to ensure that they revoke upon assignment. The handle class template has also been hardened by the removal of the implicit constructor that made it easy to write incorrect code. This also turned bugs in the OS into compiler errors fixed in this PR.
- Support for non-WinRT interfaces is disabled by default. To enable, simply #include <unknwn.h> before any C++/WinRT headers.
- winrt::get_abi(winrt::hstring) now returns void* instead of HSTRING. Code requiring the HSTRING ABI can simply use a static_cast.
- winrt::put_abi(winrt::hstring) returns void** instead of HSTRING*. Code requiring the HSTRING ABI can simply use a reinterpret_cast.
- HRESULT is now projected as winrt::hresult. Code requiring an HRESULT can simply static_cast if you need to do type checking or support type traits, but it is otherwise convertible as long as <unknwn.h> is included first.
- GUID is now projected as winrt::guid. Code implementing APIs with GUID parameters must use winrt::guid instead, but it is otherwise convertible as long as <unknwn.h> is included first.
- The signatures of WINRT_CanUnloadNow and WINRT_GetActivationFactory has changed. Code must not declare these functions at all and instead include winrt/base.h to include their declarations.
- The winrt::handle constructor is now explicit. Code assigning a raw handle value must call the attach method instead.
- winrt::clock::from_FILETIME has been deprecated. Code should use winrt::clock::from_file_time instead.
The known issues where SDK headers are generated with types in the “ABI” namespace is still persisting in this release, and Microsoft has a workaround. Feel free to check out Microsoft’s blog post for the full details on this and everything else changed in this SDK.