型システムの概要 (C++/CX)
Windows ランタイム アーキテクチャを使用すると、C++/WinRT、C++/CX、Visual Basic、Visual C#、JavaScript を使用して、アプリとコンポーネントを記述できます。 それらは Windows API に直接アクセスすることができます。また、それらを他の Windows ランタイム アプリやコンポーネントと相互運用することもできます。 C++ で記述されたユニバーサル Windows プラットフォーム (UWP) アプリは、CPU で直接実行されるネイティブ コードにコンパイルされます。 C# または Visual Basic で記述された UWP アプリは、Microsoft Intermediate Language (MSIL) にコンパイルされ、共通言語ランタイム (CLR) で実行されます。 JavaScript で記述された UWP アプリは、JavaScript 実行時環境で実行されます。 Windows ランタイム オペレーティング システムのコンポーネント自体が、C++ で記述され、ネイティブ コードとして実行されます。 これらのコンポーネントと UWP アプリはすべて、Windows ランタイム アプリケーション バイナリ インターフェイス (ABI) を介して直接通信します。
最新の C++ 表現で Windows ランタイムのサポートを有効にするため、Microsoft は C++/CX 言語拡張機能を作成しました。 C++/CX には、組み込みの基本型と、基本的な Windows ランタイム型の実装が用意されています。 これらの型を使用すると、ABI を介して、C++ アプリおよびコンポーネントと、他の言語で記述されたアプリとの通信を行うことができます。 C++/CX アプリでは、任意の Windows ランタイム型を使用できます。 また、他の UWP アプリおよびコンポーネントで使用可能なクラス、構造体、インターフェイス、およびその他のユーザー定義型を作成することもできます。 C++/CX で記述された UWP アプリでは、それがパブリック アクセシビリティを備えていない限り、正規の C++ クラスおよび構造体も使用できます。
C++/CX 言語プロジェクションと内部動作の詳しい説明については、次のブログ記事を参照してください。
Note
C++/CX は引き続きサポートされますが、新しい Windows ランタイム アプリおよびコンポーネントには、代わりに C++/WinRT を使用することをお勧めします。 これは、お客様が最新の Windows API に最適にアクセスできるように設計されています。 名前にもかかわらず、C++/WinRT では拡張機能を持たない標準の C++17 のみが使用されます。 ヘッダーのみのライブラリを使用して、Windows ランタイム API の C++ 言語プロジェクションが実装されます。 C++/WinRT は、Windows SDK バージョン 1803 (10.0.17134.0) 以降で使用できます。
Windows メタデータ (.winmd) ファイル
C++ で記述された UWP アプリをコンパイルすると、コンパイラによって、ネイティブのマシン語コードの実行可能ファイルが生成されます。また、クラス、構造体、列挙体、インターフェイス、パラメーター化されたインターフェイス、およびデリゲートなど、パブリック型の Windows ランタイムの記述を含む個別の Windows メタデータ (.winmd
) も生成されます。 メタデータの形式は、.NET Framework アセンブリで使用される形式に似ています。 C++ コンポーネントでは、.winmd
ファイルに含まれるのはメタデータのみであり、実行可能コードは、別個のファイルに存在します。 Windows に含まれる Windows ランタイム コンポーネントでは、この配置が使用されます。 .winmd
ファイルの名前はソース コードのルート名前空間のプレフィックスに一致またはそれ自体である必要があります。 (.NET Framework 言語の場合、.winmd
ファイルには、.NET Framework アセンブリのようにコードとメタデータの両方が含まれます。)
.winmd
ファイルのメタデータは、コードの公開されたサーフェイスを表します。 公開された型は、他の UWP アプリがどんな言語で記述されていようと、それらのアプリに表示されます。 メタデータ、または公開されたコードには、Windows ランタイム型システムによって指定された型だけを含めることができます。 通常のクラス、配列、テンプレート、C++ 標準ライブラリ (STL) コンテナーなど、C++ 固有の言語コンストラクトを発行することはできません。 JavaScript または C# クライアント アプリの場合は、それらを処理する方法がありません。
型またはメソッドがメタデータに表示されるかどうかは、適用されるアクセシビリティ修飾子によって異なります。 型を表示するには、型が名前空間で宣言され、public
として宣言されている必要があります。 非 public
ref class
は、コード内では内部ヘルパー型として許可されています。これはメタデータには表示されません。 public ref class
でも、すべてのメンバーが必ずしも表示されるとは限りません。 次の表は、public ref class
での C++ アクセス指定子の関係、および Windows ランタイム メタデータの可視性の一覧を示しています。
メタデータで公開 | メタデータで非公開 |
---|---|
public |
private |
protected |
internal |
public protected |
private protected |
オブジェクト ブラウザーを使用すれば、.winmd
ファイルの内容を表示することができます。 Windows に含まれている Windows ランタイム コンポーネントは、Windows.winmd
ファイルにあります。 default.winmd
ファイルには C++/CX で使用される基本型が含まれ、platform.winmd
には Platform
名前空間からの型が含まれています。 既定では、これらの 3 個の .winmd
ファイルは、UWP アプリのすべての C++ プロジェクトに含まれます。
ヒント
Platform::Collections
名前空間内の型は、パブリックではないので、.winmd
ファイルには表示されません。 これらは、Windows::Foundation::Collections
で定義されているインターフェイスの C++ 固有の非公開実装です。 JavaScript または C# で記述された Windows ランタイム アプリは、Platform::Collections::Vector
クラスがどのようなものであるかを認識しませんが、Windows::Foundation::Collections::IVector
を使用することはできます。 Platform::Collections
型は collection.h
に定義されます。
C++/CX の Windows ランタイム型システム
以下のセクションでは、Windows ランタイム型システムの主な機能、および C++/CX でのそれらの機能のサポートについて説明します。
名前空間
すべての Windows ランタイム型を 1 つの名前空間内で宣言する必要があります。Windows API 自体は、名前空間ごとに構成されています。 .winmd
ファイルには、ルート名前空間と同じ名前が必要です。 たとえば、A.B.C.MyClass
という名前のクラスは、A.winmd
、A.B.winmd
、またはA.B.C.winmd
という名前のメタデータ ファイルで定義されている場合にのみインスタンス化できます。 DLL の名前が .winmd
ファイル名と一致する必要はありません。
Windows API 自体が、名前空間ごとに構成された、十分にファクタリングされたクラス ライブラリとして再開発されました。 Windows ランタイム コンポーネントはすべて、Windows.*
名前空間で宣言されています。
詳細については、「名前空間と型の参照範囲」を参照してください。
基本的な型
Windows ランタイムでは、次の基本的な型が定義されています: UInt8
、Int16
、UInt16
、Int32
、UInt32
、Int64
、UInt64
、Single
、Double
、Char16
、Boolean
、String
。 C++/CX では、uint16
、uint32
、uint64
、int16
、int32
、int64
、float32
、float64
、および char16
として、既定の名前空間の基本的な数値型がサポートされています。 Boolean
と String
は、Platform
名前空間でも定義されています。
C++/CX には、unsigned char
と等価の uint8
も定義されています。これは、Windows ランタイムではサポートされておらず、パブリック API では使用できません。
基本型は、Platform::IBox
インターフェイスでラップすることで Null 許容にすることができます。 詳細については、「 値クラスと構造体で定義されているインターフェイスのプライベート C++ 固有の実装です。
基本型の詳細については、「 基本型
文字列
Windows ランタイム文字列は、16 ビット UNICODE 文字列の変更できないシーケンスです。 Windows ランタイムの文字列は Platform::String^
として投影されます。 このクラスは、文字列の作成、操作、および wchar_t
への変換 (およびその逆) のためのメソッドを提供します。
詳細については、「 文字列で定義されているインターフェイスのプライベート C++ 固有の実装です。
配列
Windows ランタイムでは、任意の型の 1 次元配列がサポートされています。 配列の配列はサポートされていません。 C++/CX では、Windows ランタイム配列は Platform::Array
クラスとして射影されます。
詳細については、次のトピックを参照してください。 Array
および WriteOnlyArray
ref class
および ref struct
型
Windows ランタイム クラスは、参照によってコピーされるので、C++/CX では ref class
または ref struct
として投影されます。 ref class
および ref struct
オブジェクトのメモリ管理は、参照カウントを通じて透過的に処理されます。 オブジェクトへの最後の参照がスコープ外に出ると、オブジェクトは破棄されます。 ref class
または ref struct
型では次のことができます。
コンストラクター、メソッド、プロパティ、およびイベントをメンバーとして格納できます。 これらのメンバーには、
public
、private
、protected
、またはinternal
アクセシビリティを設定できます。入れ子になった非公開の
enum
、struct
、またはclass
定義を含めることができます。1 つの基底クラスから直接継承し、任意の数のインターフェイスを実装できます。 すべての
ref class
オブジェクトは暗黙的にPlatform::Object
クラスに変換可能であり、その仮想メソッド (たとえば、Object::ToString
) をオーバーライドできます。
パブリック コンストラクターを持つ ref class
クラスは、さらに派生されることを防ぐために、sealed
として宣言する必要があります。
詳細については、「 Ref クラスと構造体
value class
および value struct
型
value class
または value struct
は基本的なデータ構造を表し、これにはフィールドのみが含まれ、その型は value class
、value struct
、または Platform::String^
とすることができます。 value struct
および value class
オブジェクトは値でコピーされます。
value struct
は、IBox
インターフェイスでラップすることで、Null 許容とすることができます。
詳細については、「 値クラスと構造体で定義されているインターフェイスのプライベート C++ 固有の実装です。
部分クラス
部分クラスの機能を使用して、1 つのクラスを複数のファイルに対して定義できます。 これにより、XAML エディターなどのコード生成ツールで、あるファイルの変更を、編集対象の別のファイルに触れずに行うことができます。
詳細については、「 部分クラス
プロパティ
プロパティは、任意の Windows ランタイム型のパブリック データ メンバーです。 これは、property
キーワードを使用して宣言および定義されています。 プロパティは、get
/set
メソッド ペアとして実装されます。 クライアント コードは、パブリック フィールドのようにプロパティにアクセスします。 カスタムの get
または set
コードを必要とするプロパティは、"trivial プロパティ" と呼ばれ、明示的な get
または set
メソッドを使用せずに宣言できます。
詳細については、「 プロパティで定義されているインターフェイスのプライベート C++ 固有の実装です。
C++/CX の Windows ランタイム コレクション
Windows ランタイムは、各言語が独自の方法で実装する、コレクション型の一連のインターフェイスを定義します。 C++/CX には、Platform::Collections::Vector
クラス、Platform::Collections::Map
クラス、およびその他の関連する具体的なコレクション型 (対応する C++ 標準ライブラリと互換性のある) の実装が用意されています。
詳細については、コレクション を参照してください。
テンプレート ref class
型
private
および internal
アクセス ref class
型は、テンプレート化して特殊化できます。
詳細については、「 テンプレート ref クラスで定義されているインターフェイスのプライベート C++ 固有の実装です。
インターフェイス
Windows ランタイム インターフェイスは、ref class
または ref struct
型が、インターフェイスから継承する場合に実装する必要がある、一連のパブリック プロパティ、メソッド、およびイベントを定義します。
詳細については、「インターフェイス」を参照してください。
列挙型
Windows ランタイムの enum class
型は、C++ のスコープ付き enum
に似ています。 基になる型は int32
です。[Flags] 属性が適用された場合、基になる型は uint32
です。
詳細については、「 列挙体で定義されているインターフェイスのプライベート C++ 固有の実装です。
デリゲート
Windows ランタイムのデリゲートは、C++ の std::function
オブジェクトに似ています。 これは、互換性のあるシグニチャを持つクライアント提供関数を呼び出すために使用される、特殊な ref class
型です。 デリゲートは、通常、イベントの型として Windows ランタイムで使用されます。
詳細については、「デリゲート」を参照してください。
例外
C++/CX では、カスタムの例外の型、std::exception
型、および Platform::Exception
型をキャッチできます。
詳細については、「 例外で定義されているインターフェイスのプライベート C++ 固有の実装です。
Events
イベントは、型がデリゲート型である ref class
または ref struct
のパブリック メンバーです。 イベントに対して可能なのは、所有するクラスによる呼び出し (つまり、発生) だけです。 ただし、クライアント コードで独自のイベント ハンドラー関数を提供することはできます。それらは、所有クラスでイベントが発生したときに呼び出されます。
詳細については、「イベント」を参照してください。
キャスト
C++/CX では、標準の C++ キャスト演算子 static_cast
、dynamic_cast
、および reinterpret_cast
がサポートされています。また、C++/CX に固有の safe_cast
演算子もサポートされています。
詳細については、「 キャストで定義されているインターフェイスのプライベート C++ 固有の実装です。
ボックス化
ボックス化された変数は、参照型でラップされる値型です。 参照セマンティクスが必要な状況では、ボックス化された変数を使用します。
詳細については、「 ボックス化で定義されているインターフェイスのプライベート C++ 固有の実装です。
属性
属性は、任意の Windows ランタイム型または型のメンバーに適用できるメタデータ値です。 属性は、実行時に検査することができます。 Windows ランタイムは、Windows::Foundation::Metadata
名前空間で一連の共通の属性を定義します。 パブリック インターフェイスのユーザー定義属性は、このリリースの Windows ランタイムではサポートされていません。
API の非推奨
Windows ランタイムのシステム型によって使用されるのと同じ属性を使用して、パブリック API に非推奨のマークを付ける方法について説明します。
詳細については、「非推奨の型とメンバー」を参照してください。