Type system overview (C++/CX)

By using the Windows Runtime architecture, you can use C++/WinRT, C++/CX, Visual Basic, Visual C#, and JavaScript to write apps and components. They can directly access the Windows API and interoperate with other Windows Runtime apps and components. Universal Windows Platform (UWP) apps that are written in C++ compile to native code that executes directly in the CPU. UWP apps that are written in C# or Visual Basic compile to Microsoft intermediate language (MSIL) and execute in the common language runtime (CLR). UWP apps that are written in JavaScript execute in a JavaScript run-time environment. The Windows Runtime operating system components themselves are written in C++ and run as native code. All of these components and UWP apps communicate directly through the Windows Runtime application binary interface (ABI).

To enable support for the Windows Runtime in a modern C++ idiom, Microsoft created the C++/CX language extension. C++/CX provides built-in base types and implementations of fundamental Windows Runtime types. These types let C++ apps and components communicate across the ABI with apps written in other languages. C++/CX apps can consume any Windows Runtime type. They may also create classes, structs, interfaces, and other user-defined types that other UWP apps and components can consume. A UWP app that's written in C++/CX can also use regular C++ classes and structs, as long as they don't have public accessibility.

For an in-depth discussion of the C++/CX language projection and how it works under the covers, see these blog posts:

Note

While C++/CX is still supported, we recommend you use C++/WinRT for new Windows Runtime apps and components instead. It's designed to provide you with first-class access to the modern Windows API. Despite the name, C++/WinRT uses only standard C++17 with no extensions. It uses a header-only library to implement a C++ language projection for Windows Runtime APIs. C++/WinRT is available in the Windows SDK from version 1803 (10.0.17134.0) onward.

Windows metadata (.winmd) files

When you compile a UWP app that's written in C++, the compiler generates the executable in native machine code, and also generates a separate Windows metadata (.winmd) file that contains descriptions of the public Windows Runtime types, which include classes, structs, enumerations, interfaces, parameterized interfaces, and delegates. The format of the metadata resembles the format that's used in .NET Framework assemblies. In a C++ component, the .winmd file contains only metadata; the executable code is in a separate file. The Windows Runtime components included with Windows use this arrangement. A .winmd file name must match or be a prefix of the root namespace in the source code. (For .NET Framework languages, the .winmd file contains both the code and the metadata, just like a .NET Framework assembly.)

The metadata in the .winmd file represents the published surface of your code. Published types are visible to other UWP apps no matter what language those other apps are written in. The metadata, or your published code, can only contain types specified by the Windows Runtime type system. You can't publish C++-specific language constructs such as regular classes, arrays, templates, or C++ Standard Library (STL) containers. A JavaScript or C# client app wouldn't know what to do with them.

Whether a type or method is visible in metadata depends on what accessibility modifiers are applied to it. To be visible, a type must be declared in a namespace and must be declared as public. A non-public ref class is permitted as an internal helper type in your code; it just isn't visible in the metadata. Even in a public ref class, not all members are necessarily visible. The following table lists the relationship between C++ access specifiers in a public ref class, and Windows Runtime metadata visibility:

Published in metadata Not published in metadata
public private
protected internal
public protected private protected

You can use the Object Browser to view the contents of .winmd files. The Windows Runtime components included with Windows are found in the Windows.winmd file. The default.winmd file contains the fundamental types that are used in C++/CX, and platform.winmd contains types from the Platform namespace. By default, these three .winmd files are included in every C++ project for UWP apps.

Tip

The types in the Platform::Collections namespace don't appear in the .winmd file because they're not public. They're private C++-specific implementations of the interfaces that are defined in Windows::Foundation::Collections. A Windows Runtime app that's written in JavaScript or C# doesn't know what a Platform::Collections::Vector class is, but it can consume a Windows::Foundation::Collections::IVector. The Platform::Collections types are defined in collection.h.

Windows Runtime type system in C++/CX

The following sections describe the major features of the Windows Runtime type system and how they're supported in C++/CX.

Namespaces

All Windows Runtime types must be declared within a namespace; the Windows API itself is organized by namespace. A .winmd file must have the same name that the root namespace has. For example, a class that's named A.B.C.MyClass can be instantiated only if it's defined in a metadata file that's named A.winmd, A.B.winmd, or A.B.C.winmd. The name of the DLL isn't required to match the .winmd file name.

The Windows API itself has been reinvented as a well-factored class library that's organized by namespaces. All Windows Runtime components are declared in the Windows.* namespaces.

For more information, see Namespaces and type visibility.

Fundamental types

The Windows Runtime defines the following fundamental types: UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Char16, Boolean, and String. C++/CX supports the fundamental numeric types in its default namespace as uint16, uint32, uint64, int16, int32, int64, float32, float64, and char16. Boolean and String are also defined in the Platform namespace.

C++/CX also defines uint8, equivalent to unsigned char, which isn't supported in the Windows Runtime and can't be used in public APIs.

A fundamental type may be made nullable by wrapping it in a Platform::IBox interface. For more information, see Value classes and structs.

For more information about fundamental types, see Fundamental types

Strings

A Windows Runtime string is an immutable sequence of 16-bit UNICODE characters. A Windows Runtime string is projected as Platform::String^. This class provides methods for string construction, manipulation, and conversion to and from wchar_t.

For more information, see Strings.

Arrays

The Windows Runtime supports one-dimensional arrays of any type. Arrays of arrays aren't supported. In C++/CX, Windows Runtime arrays are projected as the Platform::Array class.

For more information, see Array and WriteOnlyArray.

ref class and ref struct types

A Windows Runtime class is projected in C++/CX as a ref class or ref struct type, because it's copied by reference. Memory management for ref class and ref struct objects is handled transparently through reference counting. When the last reference to an object goes out of scope, the object is destroyed. A ref class or ref struct type can:

  • Contain as members constructors, methods, properties, and events. These members can have public, private, protected, or internal accessibility.

  • Can contain private nested enum, struct, or class definitions.

  • Can directly inherit from one base class and can implement any number of interfaces. All ref class objects are implicitly convertible to the Platform::Object class and can override its virtual methods—for example, Object::ToString.

A ref class that has a public constructor must be declared as sealed, to prevent further derivation.

For more information, see Ref classes and structs

value class and value struct types

A value class or value struct represents a basic data structure and contains only fields, which may be value class types, value struct types, or type Platform::String^. value struct and value class objects are copied by value.

A value struct can be made nullable by wrapping it in an IBox interface.

For more information, see Value classes and structs.

Partial classes

The partial class feature enables one class to be defined over multiple files. It lets code-generation tools such as the XAML editor modify one file without touching another file that you edit.

For more information, see Partial classes

Properties

A property is a public data member of any Windows Runtime type. It's declared and defined by using the property keyword. A property is implemented as a get/set method pair. Client code accesses a property as if it were a public field. A property that requires no custom get or set code is known as a trivial property and can be declared without explicit get or set methods.

For more information, see Properties.

Windows Runtime collections in C++/CX

The Windows Runtime defines a set of interfaces for collection types that each language implements in its own way. C++/CX provides implementations in the Platform::Collections::Vector class, Platform::Collections::Map class, and other related concrete collection types, which are compatible with their C++ Standard Library counterparts.

For more information, see Collections.

Template ref class types

private and internal access ref class types can be templated and specialized.

For more information, see Template ref classes.

Interfaces

A Windows Runtime interface defines a set of public properties, methods, and events that a ref class or ref struct type must implement if it inherits from the interface.

For more information, see Interfaces.

Enums

An enum class type in the Windows Runtime resembles a scoped enum in C++. The underlying type is int32, unless the [Flags] attribute is applied—in that case, the underlying type is uint32.

For more information, see Enums.

Delegates

A delegate in the Windows Runtime is analogous to a std::function object in C++. It's a special ref class type that's used to invoke client-provided functions that have compatible signatures. Delegates are most commonly used in the Windows Runtime as the type of an event.

For more information, see Delegates.

Exceptions

In C++/CX, you can catch custom exception types, std::exception types, and Platform::Exception types.

For more information, see Exceptions.

Events

An event is a public member in a ref class or ref struct whose type is a delegate type. An event can only be invoked—that is, fired—by the owning class. However, client code can provide its own event handler functions, which are invoked when the owning class fires the event.

For more information, see Events.

Casting

C++/CX supports the standard C++ cast operators static_cast, dynamic_cast, and reinterpret_cast, and also the safe_cast operator that's specific to C++/CX.

For more information, see Casting.

Boxing

A boxed variable is a value type that's wrapped in a reference type. Use boxed variables in situations where reference semantics are required.

For more information, see Boxing.

Attributes

An attribute is a metadata value that can be applied to any Windows Runtime type or type member. Attributes can be inspected at run time. The Windows Runtime defines a set of common attributes in the Windows::Foundation::Metadata namespace. User-defined attributes on public interfaces are not supported by Windows Runtime in this release.

API deprecation

You can mark public APIs as deprecated by using the same attribute that's used by the Windows Runtime system types.

For more information, see Deprecating types and members.

See also

C++/CX language reference