C++/WinRT の概要
C++/WinRT は Windows ランタイム (WinRT) API の標準的な最新の C++17 言語プロジェクションで、ヘッダー ファイル ベースのライブラリとして実装され、最新の Windows API への最上位アクセス権を提供するように設計されています。 C++/WinRT の場合、標準に準拠した C++17 のコンパイラを使用して Windows ランタイム API を作成および使用できます。 Windows SDK には C++/WinRT が含まれます。バージョン 10.0.17134.0 (Windows 10、バージョン 1803) で導入されました。
C++/WinRT は、C++/CX 言語プロジェクション、および Windows ランタイム C++ テンプレート ライブラリ (WRL) に代わる、Microsoft で推奨されているものです。 C++/WinRT に関するトピックの完全な一覧には、C++/CX と WRL との相互運用、C++/CX と WRL からの移行の両方に関する情報が含まれます。
重要
知っておくべき C++/WinRT の一部の最も重要な部分は、「C++/WinRT の SDK サポート」と「C++/WinRT、XAML、VSIX 拡張機能、NuGet パッケージの Visual Studio のサポート」のセクションで説明されています。
「C++/WinRT サンプル アプリはどこにありますか?」も参照してください。
言語プロジェクション
Windows ランタイムは、コンポーネント オブジェクト モデル (COM) API に基づいており、言語プロジェクションを使用してアクセスするよう設計されています。 プロジェクションは、COM の詳細を隠し、特定の言語により自然なプログラミング エクスペリエンスを提供します。
Windows ランタイム API リファレンス コンテンツにおける C++/WinRT 言語プロジェクション
Windows ランタイム API の閲覧中に、右上隅の [言語] ボックスをクリックして [C++/WinRT] を選択すると、C++/WinRT 言語プロジェクションで使用された API 構文ブロックを表示できます。
C++/WinRT、XAML、VSIX 拡張機能、NuGet パッケージの Visual Studio のサポート
Visual Studio のサポートでは、Visual Studio 2022、Visual Studio 2019、または Visual Studio 2017 が必要になります (バージョン 15.6 以上、Microsoft では 15.7 以上をお勧めします)。 Visual Studio インストーラーから、ユニバーサル Windows プラットフォーム開発ワークロードをインストールします。 まだ行っていない場合は、[インストールの詳細]>[ユニバーサル Windows プラットフォーム開発] で [C++ (v14x) ユニバーサル Windows プラットフォーム ツール] オプションを選択します。 また、Windows の [設定]>[プライバシーとセキュリティ] (Windows 10: [更新とセキュリティ]) >[開発者向け] で、[開発者モード] オプション (Windows 10: [サイドロード アプリ] オプションではない方) を有効にします。
最新バージョンの Visual Studio と Windows SDK で開発することをお勧めしますが、10.0.17763.0 (Windows 10、バージョン 1809) より前の Windows SDK に付属する C++/WinRT のバージョンを使用している場合、上記で示した Windows 名前空間ヘッダーを使用するには、10.0.17134.0 (Windows 10、バージョン 1803) のプロジェクトで最小の Windows SDK ターゲット バージョンが必要になります。
Visual Studio 2022 は、C++/WinRT 開発をすぐに開始できるように、C++/WinRT プロジェクトと項目テンプレートが組み込まれて出荷されます。 また、C++/WinRT の投影された型の Visual Studio ネイティブのデバッグの視覚化 (NatVis) も提供されるため、C# デバッグと同様のエクスペリエンスが実現されます。 Natvis はデバッグ ビルドで自動で行われます。 詳細については、「C++/WinRT 用 Visual Studio ネイティブ デバッグ視覚化」を参照してください。
以前のバージョンの Visual Studio の場合、Visual Studio Marketplace から最新バージョンの C++/WinRT Visual Studio 拡張機能 (VSIX) をダウンロードしてインストールする必要があります。
- VSIX 拡張機能では、Visual Studio で C++/WinRT プロジェクトと項目テンプレートが提供されます。
- さらに、これにより、C++/WinRT の投影された型の Visual Studio ネイティブのデバッグの視覚化 (NatVis) が実現します。
C++/WinRT 用の Visual Studio プロジェクト テンプレートは、以下のセクションで説明されます。 最新バージョンの VSIX 拡張機能がインストールされた新しい C++/WinRT プロジェクトを作成する場合、新しい C++/WinRT プロジェクトで自動的に Microsoft.Windows.CppWinRT NuGet パッケージがインストールされます。 Microsoft.Windows.CppWinRT NuGet パッケージでは、C++/WinRT のビルド (MSBuild プロパティとターゲット) がサポートされ、自分のプロジェクトを (NuGet パッケージのみ (VSIX 拡張機能以外) がインストールされる) 開発マシンとビルド エージェントとの間で移植できるようになります。
または、Microsoft.Windows.CppWinRT NuGet パッケージを手動でインストールすることで、既存のプロジェクトを変換できます。 最新バージョンの VSIX 拡張機能をインストール (または更新) 後、Visual Studio で既存のプロジェクトを開き、[プロジェクト]>[NuGet パッケージの管理...]>[参照] とクリックし、検索ボックスに Microsoft.Windows.CppWinRT と入力または貼り付けます。検索結果の項目を選択し、[インストール] をクリックしてそのプロジェクトのパッケージをインストールします。 そのパッケージを追加したら、cppwinrt.exe
ツールの呼び出しを含む、プロジェクトの C++/WinRT MSBuild サポートを取得できます。
重要
1\.0.190128.4 より前の VSIX 拡張機能のバージョンで作成された (作業するためにアップグレードされた) プロジェクトがある場合は、「VSIX 拡張機能の以前のバージョン」を参照してください。 そのセクションには、プロジェクトの構成に関する重要な情報が含まれ、最新バージョンの VSIX 拡張機能を使用するためにアップグレードする必要があるものを把握します。
- C++/WinRT では C++17 標準の機能が使用されるので、NuGet パッケージでは Visual Studio でプロジェクト プロパティの [C/C++]>[言語]>[C++ 言語標準]>[ISO C++17 標準 (/std:c++17)] を設定します。
- これにより、/bigobj コンパイラ オプションも追加されます。
co_await
を有効にするために、/await コンパイラ オプションが追加されます。- C++/WinRT codegen を出力するよう、XAML コンパイラに指示されます。
- Conformance mode:Yes (/permissive-) を設定する可能性もあり、これはコードを標準に準拠しているようにさらに制限します。
- 注意すべきもう 1 つのプロジェクト プロパティは、 [C/C++]>[全般]>[警告をエラーとして扱う] です。 これをユーザーの好みに合わせて [はい (/WX)] または [いいえ (/WX-)] に設定します。 場合によっては、
cppwinrt.exe
ツールによって生成されたソース ファイルは、それらに実装を追加するまで警告を生成します。
上記で説明されているように設定されたシステムでは、Visual Studio で C++/WinRT プロジェクトを作成してビルドし (または開いて)、展開することができます。
バージョン 2.0 の Microsoft.Windows.CppWinRT NuGet パッケージには、cppwinrt.exe
ツールが含まれます。 cppwinrt.exe
ツールは Windows ランタイム メタデータ (.winmd
) ファイルでポイントして、C++/WinRT コードから使用するためのメタデータに記述されている API を投影するヘッダー ファイル ベースの標準的な C++ ライブラリを生成することができます。 Windows ランタイム メタデータ (.winmd
) ファイルは、Windows ランタイム API サーフェスを記述する正規の方法を提供します。 メタデータで cppwinrt.exe
をポイントすることで、セカンド パーティまたはサード パーティの Windows ランタイム コンポーネントに実装された、または独自のアプリケーションに実装された任意のランタイム クラスで使用するためのライブラリを生成することができます。 詳細については、「C++/WinRT での API の使用」を参照してください。
C++/WinRT では、COM スタイルのプログラミングを使用せずに、標準的な C++ を使用して独自のランタイム クラスを実装することもできます。 ランタイム クラスでは、IDL ファイルで型を記述するだけです。midl.exe
および cppwinrt.exe
が実装のスケルトン ソース コード ファイルを自動的に作成します。 または、C++/WinRT の基本クラスから派生することでインターフェイスを実装することもできます。 詳細については、「C++/WinRT での API の作成」を参照してください。
プロジェクトのプロパティによって設定される cppwinrt.exe
ツールのカスタマイズ オプションの一覧については、Microsoft.Windows.CppWinRT NuGet パッケージの readme をご覧ください。
プロジェクト内にインストールされた Microsoft.Windows.CppWinRT NuGet パッケージのプレゼンスによって、C++/WinRT MSBuild サポートを使用するプロジェクトを識別できます。
VSIX 拡張機能によって提供される Visual Studio プロジェクト テンプレートを次に示します。
空のアプリ (C++/WinRT)
XAML ユーザー インターフェイスを持つユニバーサル Windows プラットフォーム (UWP) アプリのプロジェクト テンプレートです。
Visual Studio では、各 XAML マークアップ ファイルの背後にあるインターフェイス定義言語 (IDL) (.idl
) ファイルから実装とヘッダーのスタブを生成するために XAML コンパイラ サポートを提供します。 IDL ファイルで、アプリの XAML ページ内で参照する任意のローカルのランタイム クラスを定義してから、プロジェクトを 1 回ビルドして Generated Files
で実装テンプレート、Generated Files\sources
でスタブ型定義を生成します。 次に、ローカルのランタイム クラスの実装への参照にこれらのスタブ型定義を使用します。 「ランタイム クラスを Midl ファイル (.idl) にファクタリングする」を参照してください。
C++/WinRT に対する Visual Studio での XAML デザイン サーフェスのサポートは、C# でのパリティに類似します。 Visual Studio では、 [プロパティ] ウィンドウの [イベント] タブを使用して、C++/WinRT プロジェクト内にイベント ハンドラーを追加できます。 また、自分のコードに手動でイベント ハンドラーを追加することもできます。詳細については、「C++/WinRT でのデリゲートを使用したイベントの処理」を参照してください。
コア アプリ (C++/WinRT)
XAML を使用しないユニバーサル Windows プラットフォーム (UWP) アプリのプロジェクト テンプレートです。
代わりに、Windows.ApplicationModel.Core 名前空間に C++/WinRT Windows 名前空間ヘッダーを使用します。 ビルドおよび実行した後に、空の領域をクリックして色付きの正方形を追加し、色付きの正方形をクリックしてそれをドラッグします。
Windows コンソール アプリケーション (C++/WinRT)
コンソールのユーザー インターフェイスを含む、Windows デスクトップの C++/WinRT クライアント アプリケーションのプロジェクト テンプレートです。
Windows デスクトップ アプリケーション (C++/WinRT)
Windows Desktop 用の C++/WinRT クライアント アプリケーションに対するプロジェクト テンプレートでは、Win32 MessageBox 内に Windows ランタイム Windows.Foundation.Uri が表示されます。
Windows ランタイム コンポーネント (C++/WinRT)
通常はユニバーサル Windows プラットフォーム (UWP) から使用するための、コンポーネントのプロジェクト テンプレートです。
このテンプレートは、Windows ランタイム メタデータ (.winmd
) が IDL から生成され、実装とヘッダーのスタブが Windows ランタイム メタデータから生成される、midl.exe
>cppwinrt.exe
ツール チェーンを示します。
IDL ファイルでは、コンポーネント、それらの既定インターフェイス、およびそれらが実装している他のすべてのインターフェイスのランタイム クラスを定義します。 プロジェクトを 1 回ビルドして module.g.cpp
、module.h.cpp
、Generated Files
の実装テンプレート、および Generated Files\sources
のスタブ型定義を生成します。 次にコンポーネント内のランタイム クラスの実装への参照にこれらのスタブ型定義を使用します。 「ランタイム クラスを Midl ファイル (.idl) にファクタリングする」を参照してください。
ビルドした Windows ランタイム コンポーネントのバイナリとその .winmd
を、それらを使用する UWP アプリとバンドルします。
VSIX 拡張機能の以前のバージョン
最新バージョンの VSIX 拡張機能をインストール (またはアップグレード) することをお勧めします。 既定では、それ自体で更新されるように構成されています。 これを行い、1.0.190128.4 以前の VSIX 拡張機能のバージョンで作成されたプロジェクトがある場合、このセクションには新しいバージョンで動作するように、これらのプロジェクトのアップグレードに関する重要な情報が含まれます。 更新しない場合は、引き続きこのセクションでの情報が役に立つことがわかります。
サポートされる Windows SDK と Visual Studio のバージョン、Visual Studio の構成に関して、上記の「C++/WinRT、XAML、VSIX 拡張機能、NuGet パッケージの Visual Studio のサポート」セクションの情報は、以前のバージョンの VSIX 拡張機能に適用されます。 下記の情報は、以前のバージョンで作成された (または作業を行うためにアップグレードされた) 動作とプロジェクトの構成に関して重要な違いについて説明します。
1\.0.181002.2 より前に作成
プロジェクトが 1.0.181002.2 より前の VSIX 拡張機能のバージョンで作成された場合、C++/WinRT ビルドのサポートはそのバージョンの VSIX 拡張機能に組み込まれます。 ご利用のプロジェクトには、.vcxproj
ファイルに <CppWinRTEnabled>true</CppWinRTEnabled>
プロパティ セットがあります。
<Project ...>
<PropertyGroup Label="Globals">
<CppWinRTEnabled>true</CppWinRTEnabled>
...
Microsoft.Windows.CppWinRT NuGet パッケージを手動でインストールすることで、自分のプロジェクトをアップグレードできます。 最新バージョンの VSIX 拡張機能をインストール (または更新) 後、Visual Studio でプロジェクトを開き、[プロジェクト]>[NuGet パッケージの管理...]>[参照] とクリックし、検索ボックスに Microsoft.Windows.CppWinRT と入力または貼り付けます。検索結果の項目を選択し、[インストール] をクリックしてプロジェクトのパッケージをインストールします。
1\.0.181002.2 から 1.0.190128.3 の間で作成 (またはアップグレード)
プロジェクトが 1.0.181002.2 から 1.0.190128.3 (含む) の間の VSIX 拡張機能のバージョンで作成された場合、Microsoft.Windows.CppWinRT NuGet パッケージはプロジェクト テンプレートによってプロジェクトに自動的にインストールされています。 この範囲の VSIX 拡張機能のバージョンを使用するために、以前のプロジェクトをアップグレードしている可能性もあります。 この操作を行った場合、ビルドのサポートは引き続きこの範囲内の VSIX 拡張機能のバージョンでも表されるため、ご利用のアップグレードされたプロジェクトでは Microsoft.Windows.CppWinRT NuGet パッケージをインストールしている、またはしていない可能性があります。
プロジェクトをアップグレードするには、前のセクションの手順に従って、自分のプロジェクトに確実に Microsoft.Windows.CppWinRT NuGet パッケージをインストールします。
無効なアップグレードの構成
最新バージョンの VSIX 拡張機能では、Microsoft.Windows.CppWinRT NuGet パッケージもインストールされていない場合は、プロジェクトで <CppWinRTEnabled>true</CppWinRTEnabled>
プロパティを含めることはできません。 この構成のプロジェクトでは、ビルド エラー メッセージの "The C++/WinRT VSIX no longer provides project build support. Please add a project reference to the Microsoft.Windows.CppWinRT Nuget package" (C++/WinRT VSIX ではプロジェクトのビルドがサポートされなくなりました。Microsoft.Windows.CppWinRT Nuget パッケージへのプロジェクト参照を追加してください) が生成されます。
上記で説明したように、C++/WinRT プロジェクトでは NuGet パッケージがインストールされている必要があるようになりました。
<CppWinRTEnabled>
要素は古くなったため、必要に応じて .vcxproj
を編集して、要素を削除できます。 厳密には必要ではありませんが、これはオプションです。
また、.vcxproj
には <RequiredBundles>$(RequiredBundles);Microsoft.Windows.CppWinRT</RequiredBundles>
が含まれる場合は、C++/WinRT VSIX 拡張機能をインストールすることなく、ビルドできるように、これを削除できます。
C++/WinRT の SDK サポート
これは互換性の理由のためのみで示されていますが、バージョン 10.0.17134.0 (Windows 10 バージョン 1803) の時点で、Windows SDK には、ファーストパーティ Windows API (Windows 名前空間の Windows ランタイム API) を使用するためのヘッダー ファイル ベースの標準的な C++ ライブラリが含まれています。 それらのヘッダーは %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt
フォルダー内にあります。 Windows SDK バージョン 10.0.17763.0 (Windows 10、バージョン 1809) の時点で、これらのヘッダーは、プロジェクト内の $(GeneratedFilesDir) フォルダー内で生成されます。
繰り返しになりますが、互換性のために、Windows SDK は cppwinrt.exe
ツールにも付属しています。 しかし、代わりに最新バージョンの cppwinrt.exe
をインストールして使用することをお勧めします。これは、Microsoft.Windows.CppWinRT NuGet パッケージに含まれています。 そのパッケージ (および cppwinrt.exe
) は、上記のセクションで説明されています。
C++/WinRT プロジェクションにおけるカスタム型
自分の C++/WinRT プログラミングで、標準 C++ 言語機能および標準 C++ データ型と C++/WinRT を使用できます。一部の C++ 標準ライブラリのデータ型を含みます。 ただし、プロジェクションでいくつかのカスタム データ型を認識するようになり、それらを使用することもできます。 たとえば、C++/WinRT の概要 のクイックスタートのコード例では winrt::hstring を使用しています。
winrt::com_array は、あるポイントで使用する可能性が高い別の型です。 ただし、winrt::array_view などの型を直接使用する可能性は低いです。 または、対応する型が C++ 標準ライブラリに現れた場合に変更すべきコードがないように、使用しないことを選択する場合もあります。
警告
C++/WinRT Windows 名前空間ヘッダーをよく調査すると見つかる可能性がある型もあります。 例として winrt::param::hstring がありますが、コレクションの例もあります。 これらは入力パラメーターのバインディングを最適化するためにのみ存在し、大幅に改善したパフォーマンスをもたらし、関連する標準的な C++ の型とコンテナーでほとんどの呼び出しパターンが "そのまま機能する" ようにします。 これらの型は、ほとんどの値を追加する場合にプロジェクションでのみ使用されます。 高度に最適化され、一般的な用途で使用するものではありません。それらの型を自分で使用しないようにしてください。 また、winrt::impl
名前空間からは何も使用しないでください。それらは実装型であるため、変更されることがあります。 引き続き標準型を使用するか、または winrt 名前空間の型を使用する必要があります。
また、「ABI 境界へのパラメーターの受け渡し」もご覧ください。