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
generickeyword, similar to C++ templates. - Metadata Export: While WinRT generics preserve their genericity in metadata, C++ template instantiations are exported to
.winmdmetadata 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:
- 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.
- C++/CX (Component Extensions): A legacy option that uses extensions (like
ref newand the^hat operator) to integrate with the type system. It supports partial classes to separate machine-generated XAML code from human-written logic. - WRL (Windows Runtime C++ Template Library): An ATL-style template library that is exception-free and relies on
HRESULTreturn 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
asyncmethod, following the<Verb>[<Noun>]Asyncnaming 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
| 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".