WinRT Architecture and Programming Model

WinRT Architecture and Programming Model

The Windows Runtime (WinRT) is a sophisticated programming model designed to enable object-oriented code to be shared across multiple programming languages. At its core, WinRT allows developers to build applications that feel native to their chosen language while maintaining a consistent binary interface across the Windows ecosystem.

The Role of Metadata

Metadata is the foundation of the WinRT ABI (Application Binary Interface). It defines the programming model and enables services such as reflective programming (reflection), which allows a program to inspect its own structure at runtime.

Because native machine code cannot contain metadata, WinRT stores this information in separate metadata files. According to C++ expert Herb Sutter, this format is identical to CLI (Common Language Infrastructure) metadata. This alignment allows WinRT APIs to be consumed by managed CLI languages as if they were standard .NET APIs.

[ไม่มีภาพประกอบ]

Type System and Generics

WinRT utilizes a rich, class-based type system that supports methods, properties, delegates, and events. A significant evolution from COM (Component Object Model) is the introduction of .NET-style generics.

  • Generic Scope: Only interfaces (parameterized interfaces) and delegates can be generic; runtime classes and their methods cannot.
  • C++/CX Implementation: Uses the generic keyword, similar to C++ templates.
  • Metadata Export: While WinRT generics preserve their genericity in metadata, C++ template instantiations are exported to .winmd metadata using name mangling.

WinRT also provides generic containers that parallel the C++ Standard Library. While .NET languages (C#, VB) and JavaScript handle these collections transparently through automated mappings, C++ developers use reciprocal conversion functions.

WinRT Components and Language Projections

Classes compiled for the WinRT are known as WinRT components. These can be authored in any supported language and platform, provided they include the necessary metadata to allow other languages to interface with them.

In WinRT, the process of making an API available to a specific language is called a language projection. This ensures that the API feels natural to the developer, regardless of whether they are using a managed or native language.

C++ Projections

C++ is a primary citizen of the WinRT platform. There are three main ways to interface with it:

  1. C++/WinRT: Introduced in Windows 10 (version 1803), this is a standard C++17 header-file-based library. It requires no language extensions and works with any standards-compliant C++17 compiler.
  2. C++/CX (Component Extensions): A legacy option that uses extensions (like ref new and the ^ hat operator) to integrate with the type system. It supports partial classes to separate machine-generated XAML code from human-written logic.
  3. WRL (Windows Runtime C++ Template Library): An ATL-style template library that is exception-free and relies on HRESULT return values.

.NET and Managed Languages

The Common Language Runtime (CLR) is integrated as a subplatform, providing JIT-compilation and garbage collection. WinRT applications using .NET typically utilize WinUI (XAML-based). With the release of .NET 5, built-in WinRT support was replaced by CsWinRT, a tool that generates interop code similar to C++/WinRT.

JavaScript and Other Languages

WinRT supports HTML and JavaScript, utilizing the Trident rendering engine and Chakra JavaScript engine. APIs are adapted to follow JavaScript naming conventions and namespaces are mapped to JavaScript objects. Additionally, Rust/WinRT (part of the Windows App SDK) allows Rust developers to author and consume WinRT APIs.

Key Facts

  • Metadata Format: Uses the same format as CLI metadata to enable cross-language compatibility.
  • Asynchrony Rule: Any method expected to take longer than 50ms must be an async method, following the <Verb>[<Noun>]Async naming pattern.
  • Language Projections: The mechanism that maps WinRT APIs to the natural syntax of languages like C#, C++, and JavaScript.
  • C++/WinRT: The modern, standard C++17 projection that avoids language extensions.
  • UWP Bridges: API bridges exist for iOS (Cocoa Touch), Progressive Web Apps, Silverlight, and traditional desktop apps via MSIX.

Technical Constraints and Data Mapping

WinRT Data Type and Behavior Mapping
Feature .NET / C++ JavaScript WinRT Constraint
Numerals Rich set of types Up to 53-bit precision No 8-bit signed integer
Strings Immutable (.NET) / Mutable (C++) Immutable Nulls converted to empty strings (except JS)
Structs Value types Not directly supported Only value semantics allowed (no pointers)
Arrays Reference types Reference types Value types (restricted)
Overloading Parameter and Type Parameter only Parameter number only

Frequently Asked Questions

What is a language projection in WinRT?

A language projection is the process of mapping WinRT APIs so they can be used with the natural syntax and conventions of a specific programming language, such as C# or JavaScript, rather than forcing the developer to use a low-level ABI.

How does WinRT handle asynchronous operations?

WinRT mandates that any method taking longer than 50 milliseconds must be implemented as an asynchronous method. These methods follow a specific naming convention, ending with the suffix "Async".

What is the difference between C++/CX and C++/WinRT?

C++/CX is a legacy projection that uses non-standard language extensions (like the hat operator). C++/WinRT is a modern, standard C++17 header-only library that requires no extensions and is compatible with any standard C++17 compiler.

Are there restrictions on managed WinRT components?

Yes. Classes defined in managed .NET WinRT components must be declared as sealed, meaning they cannot be inherited from. Additionally, members interfacing with other languages must use WinRT-compatible types.

How are strings handled when passing null values to WinRT?

In C++ and .NET, a null string is converted to an empty string. In JavaScript, however, passing null or undefined results in a string containing the word "null".