C++/WinRT の後続バージョンがリリースされると、このトピックに新機能と変更点が記載されます。
2020 年 3 月現在における最新の機能強化および追加のロールアップ
ビルド時間を最大 23% 短縮
C++/WinRT と C++ コンパイラ チームは、ビルド時間短縮のために可能なすべてのことを共同で行ってきました。 コンパイラ分析に注力し、C++ コンパイラでコンパイル時のオーバーヘッドを解消できるように C++/WinRT の内部を再構築する方法と、C++/WinRT ライブラリを処理するために C++ コンパイラ自体を改善する方法を見つけ出しました。 C++/WinRT はコンパイラ用に最適化されており、コンパイラも C++/WinRT 用に最適化されています。
たとえば、すべての C++/WinRT プロジェクション名前空間ヘッダーを含むプリコンパイル済みヘッダー (PCH) を構築するという最悪のシナリオを考えてみましょう。
バージョン | PCH のサイズ (バイト) | 回数 |
---|---|---|
7 月からの C++/WinRT、および Visual C++ 16.3 | 3,004,104,632 | 31 |
バージョン 2.0.200316.3 の C++/WinRT、および Visual C++ 16.5 | 2,393,515,336 | 二十四 |
サイズが 20% 削減され、ビルド時間が 23% 短縮されます。
MSBuild サポートの向上
さまざまなシナリオの大規模な選択に対する MSBuild サポートの改善に多くの作業を費やしてきました。
ファクトリ キャッシュのさらなる高速化
インライン ホット パスを向上させるために、ファクトリ キャッシュのインライン化を改善し、より高速な実行を実現しました。
この改善はコード サイズには影響しません。以下の 「最適化された EH コード生成」で説明するように、アプリケーションで C++ 例外処理が頻繁に使用されている場合は、visual Studio 2019 16.3 以降で作成された新しいプロジェクトで既定でオンになっている /d2FH4
オプションを使用してバイナリを圧縮できます。
より効率的なボックス化
XAML アプリケーションで使用すると、 winrt::box_value がより効率的になりました ( ボックス化とボックス化解除を参照)。 また、多数のボックス化を実行するアプリケーションでは、コード サイズも小さくなります。
IInspectable を実装する COM インターフェイスの実装のサポート
IInspectable を実装するだけの (Windows-Runtime以外の) COM インターフェイスを実装する必要がある場合は、C++/WinRT で実装できるようになりました。 IInspectable を実装する COM インターフェイスを参照してください。
モジュール ロックの機能強化
モジュール ロックの制御により、カスタム ホスティング シナリオと、モジュール レベル ロックの完全な排除の両方が可能になりました。 モジュール ロックの機能強化を参照してください。
Windows ランタイム以外のエラー情報のサポート
一部の API では (一部の Windows ランタイム API でも)、Windows ランタイム エラー発生 API を使用せずにエラーが報告されます。 このような場合、C++/WinRT では COM エラー情報が使用されるようになりました。 WinRT 以外のエラー情報については、C++/WinRT のサポートを参照してください。
C++ モジュール サポートの有効化
C++ モジュール サポートが再度有効になりましたが、まだ試験的な段階にすぎません。 この機能は、C++ コンパイラではまだ完全ではありません。
コルーチン再開のさらなる効率化
C++/WinRT コルーチンは既に良好なパフォーマンスを発揮していますが、さらに向上させるための方法の調査は引き続き行われています。 コルーチン再開のスケーラビリティの向上を参照してください。
新しい when_all と when_any 非同期ヘルパー
when_all ヘルパー関数は、指定されたすべての待機可能オブジェクトが完了したときに完了する IAsyncAction オブジェクトを作成します。 指定された待機可能オブジェクトのいずれかが完了すると、IAsyncAction が完了するように when_any ヘルパーが作成されます。
when_any 非同期ヘルパーの追加とwhen_all 非同期ヘルパーの追加を参照してください。
その他の最適化と追加
さらに、多数のバグ修正、軽度の最適化、および追加が導入されました。これには、デバッグを簡略化し、内部および既定の実装を最適化するためのさまざまな機能強化が含まれています。 完全な一覧については、こちらのリンクを参照してください。https://github.com/microsoft/xlang/pulls?q=is%3Apr+is%3Aclosed
C++/WinRT 2.0 の新機能と変更点
C++/WinRT Visual Studio 拡張機能 (VSIX)、Microsoft.Windows.CppWinRT NuGet パッケージ、cppwinrt.exe
ツール (取得およびインストール方法など) の詳細については、Visual Studio での C++/WinRT、XAML、VSIX 拡張機能、NuGet パッケージのサポートを参照してください。
バージョン 2.0 の C++/WinRT Visual Studio Extension (VSIX) の変更点
- デバッグ ビジュアライザーは、引き続き Visual Studio 2017 をサポートするのに加えて、Visual Studio 2019 をサポートするようになります。
- 多くのバグ修正が行われました。
バージョン 2.0 の Microsoft.Windows.CppWinRT NuGet パッケージの変更点
- 必要に応じてプロジェクトごとにプラットフォーム プロジェクション ヘッダーを生成する
cppwinrt.exe
ツールは、Microsoft.Windows.CppWinRT NuGet パッケージに含まれるようになります。 その結果、cppwinrt.exe
ツールは Windows SDK に依存しなくなります (ただし、互換性の理由から、ツールには引き続き SDK が付属しています)。 - 並列ビルドを有効にするため、
cppwinrt.exe
では各プラットフォーム/構成固有の中間フォルダー ($IntDir) の下に、プロジェクション ヘッダーが生成されるようになりました。 - プロジェクト ファイルを手動でカスタマイズする場合のため、C++/WinRT のビルドのサポート (プロパティ/ターゲット) が完全にドキュメント化されるようになりました。 Microsoft.Windows.CppWinRT NuGet パッケージ の readme を参照してください。
- 多くのバグ修正が行われました。
バージョン 2.0 での C++/WinRT の変更点
オープンソース
cppwinrt.exe
ツールは、Windows ランタイム メタデータ (.winmd
) ファイルを取得し、そこから、メタデータに記述されている API を投影するヘッダー ファイル ベースの標準 C++ ライブラリを生成します。 それにより、C++/WinRT のコードからそれらの API を使用できます。
このツールは完全なオープン ソース プロジェクトになり、GitHub で入手できます。
xlang ライブラリ
完全に移植可能なヘッダーのみのライブラリ (Windows ランタイムで使用される ECMA-335 メタデータ形式の解析用) により、今後のすべての Windows ランタイムおよび xlang ツールの基礎が形成されます。 特に、cppwinrt.exe
ツールは xlang ライブラリを使ってまったく新しく書き直しました。 これにより、メタデータのより正確なクエリが提供されるようになり、C++/WinRT 言語プロジェクションに関する長期にわたるいくつかの問題が解決されます。
依存関係の数の削減
xlang メタデータ リーダーにより、cppwinrt.exe
ツール自体の依存関係の数が少なくなります。 これにより、柔軟性が増し、より多くのシナリオ (特に、制限の厳しいビルド環境) で使用できるようになります。 特に、RoMetadata.dll
に依存しなくなります。
cppwinrt.exe
2.0 での依存関係は次のとおりです。
- ADVAPI32.dll
- KERNEL32.dll
- SHLWAPI.dll
- XmlLite.dll
Windows 10 だけでなく、Windows 7 までの旧バージョンや Windows Vista でも、これらの DLL をすべて利用できます。 そうしたければ、Windows 7 を実行中の古いビルド サーバーでも、cppwinrt.exe
を実行して、プロジェクトの C++ ヘッダーを生成できるようになりました。 少しの作業を加えれば、興味があれば、Windows 7で C++/WinRT を実行
上記の一覧を、次の cppwinrt.exe
1.0 の依存関係と比べてください。
- ADVAPI32.dll
- SHELL32.dll
- api-ms-win-core-file-l1-1-0.dll
- XmlLite.dll
- api-ms-win-core-libraryloader-l1-2-0.dll
- api-ms-win-core-processenvironment-l1-1-0.dll
- RoMetadata.dll
- SHLWAPI.dll
- KERNEL32.dll
- api-ms-win-core-rtlsupport-l1-1-0.dll
- api-ms-win-core-heap-l1-1-0.dll
- api-ms-win-core-timezone-l1-1-0.dll
- api-ms-win-core-console-l1-1-0.dll
- api-ms-win-core-localization-l1-2-0.dll
- OLEAUT32.dll
- api-ms-win-core-winrt-error-l1-1-0.dll
- api-ms-win-core-winrt-error-l1-1-1.dll
- api-ms-win-core-winrt-l1-1-0.dll
- api-ms-win-core-winrt-string-l1-1-0.dll
- api-ms-win-core-synch-l1-1-0.dll
- api-ms-win-core-threadpool-l1-2-0.dll
- api-ms-win-core-com-l1-1-0.dll
- api-ms-win-core-com-l1-1-1.dll
- api-ms-win-core-synch-l1-2-0.dll
Windows ランタイムの noexcept
属性
Windows ランタイムには、[noexcept]
でメソッドとプロパティを装飾するために使用できる新しい属性があります。 この属性が存在すると、実装で例外がスローされない (エラー HRESULT も返されない) ことをサポート ツールに示します。 これにより、言語プロジェクションでは、失敗する可能性のあるアプリケーション バイナリ インターフェイス (ABI) の呼び出しをサポートするために必要な例外処理のオーバーヘッドを回避することで、コードの生成を最適化することができます。
C++/WinRT では、使用コードと作成コード両方の C++ noexcept
の実装を生成することによって、これを利用します。 エラーが発生しない API のメソッドまたはプロパティがあり、コードのサイズを考慮することが必要な場合は、この属性を検討できます。
最適化されたコード生成
C++ コンパイラで可能な限り小さくて効率的なバイナリ コードを生成できるよう、C++/WinRT ではいっそう効率的な C++ ソース コードが (バックグラウンドで) 生成されるようになります。 不要なアンワインド情報を回避することで、例外処理のコストの削減を目的とする多くの機能強化が行われています。 大量の C++WinRT コードを使うバイナリでは、コードのサイズが約 4% 削減されます。 また、命令の数が減るため、コードがいっそう効率的に (より速く実行されるように) なります。
これらの機能強化は、使用可能な新しい相互運用機能にも依存します。 リソース所有者であるすべての C++/WinRT 型には、前の 2 つのステップのアプローチを回避し、所有権を直接取得するためのコンストラクターが含まれます。
ABI::Windows::Foundation::IStringable* raw = ...
IStringable projected(raw, take_ownership_from_abi);
printf("%ls\n", projected.ToString().c_str());
最適化された例外処理 (EH) コード生成
この変更は、Microsoft C++ オプティマイザー チームによって行われた作業を補完して、例外処理のコストを削減します。 アプリケーション バイナリ インターフェイス (ABI) (COM など) をコード内で大量に使う場合、このパターンに従うコードを多く目にします。
int32_t Function() noexcept
{
try
{
// code here constitutes unique value.
}
catch (...)
{
// code here is always duplicated.
}
}
C++/WinRT 自体では、実装されているすべての API に対してこのパターンが生成されます。 何千もの API 関数において、ここでの最適化が重要である可能性があります。 これまで、オプティマイザーではそれらの catch ブロックがすべて同じであることは検出されなかったため、各 ABI で多くのコードが重複していました (それは、システム コードで例外を使うと大きなバイナリが生成されるという確信の原因になっていました)。 しかし、Visual Studio 2019 以降の C++ コンパイラでは、それらのすべての catch funclet が折りたたまれていて、固有のものだけが格納されます。 結果として、このパターンに大きく依存するバイナリのコード サイズは全体的としてさらに 18% 減少します。 EH コードがリターン コードを使うより効率的になっただけでなく、大きいバイナリ ファイルに関する心配は過去のものになりました。
インクリメンタル ビルドの機能強化
cppwinrt.exe
ツールでは、生成されたヘッダー/ソース ファイルの出力がディスク上の既存のファイルの内容と比較されて、ファイルが実際に変更されている場合にのみ、ファイルが書き込まれます。 これにより、ディスク I/O の時間がかなり短縮され、C++ コンパイラによってファイルが "ダーティ" と見なされないことが保証されます。 結果として、多くの場合に、再コンパイルが回避または縮小されます。
ジェネリック インターフェイスがすべて生成されるようになった
xlang メタデータ リーダーのため、C++/WinRT では、すべてのパラメーター化された、またはジェネリック インターフェイスがメタデータから生成されるようになりました。
Windows::Foundation::Collections::IVector<T> などのインターフェイスが、winrt/base.h
で手動で記述されるのではなく、メタデータから生成されるようになりました。 その結果、winrt/base.h
のサイズが半分になり、最適化がコードですぐに生成されます (手書きのアプローチではこれを行うのは大変でした)。
重要
示されている例のようなインターフェイスは、winrt/base.h
ではなく、それぞれの名前空間のヘッダーに存在するようになります。 そのため、まだそのようにしていない場合、インターフェイスを使うには、適切な名前空間のヘッダーをインクルードする必要があります。
コンポーネントの最適化
この更新では、以下のセクションで説明するように、C++/WinRT に対して複数の追加オプトイン最適化のサポートが追加されています。 これらの最適化は破壊的変更なので (サポートするために小さな変更を行う必要があります)、明示的に有効にする必要があります。 Visual Studio で、プロジェクトプロパティ <CppWinRTOptimized>true</CppWinRTOptimized>
が追加されます。 また、コマンド ラインから -opt[imize]
を呼び出すときに cppwinrt.exe
スイッチを追加するのと同じ効果があります。
(プロジェクト テンプレートからの) 新しいプロジェクトでは、-opt
が既定で使われます。
均一コンストラクション、実装への直接アクセス
これら 2 つの最適化により、コンポーネントでは、プロジェクションが実行された型のみを使う場合であっても、独自の実装型に直接アクセスできます。 単にパブリック API サーフェスを使用する場合は、 make、 make_self、 get_self を使用する必要はありません。 呼び出しは実装の直接呼び出しにコンパイルされ、完全にインライン化される可能性さえあります。
詳細とコード例については、「 統一された構築へのオプトイン」および「実装への直接アクセス」を参照してください。
型消去されたファクトリ
この最適化により、module.g.cpp
に #include の依存関係がなくなり、1 つの実装クラスで変更が発生するたびに再コンパイルをする必要がなくなります。 結果として、ビルドのパフォーマンスが向上します。
複数のライブラリを含む大規模なプロジェクトに対する module.g.cpp
のスマートさと効率の向上
module.g.cpp
ファイルには、winrt_can_unload_now と winrt_get_activation_factory という名前の 2 つの追加のコンポーザブル ヘルパーも含まれるようになりました。 これらは、それぞれに独自のランタイム クラスが含まれる多数のライブラリで DLL が構成される、大規模なプロジェクト向けに設計されています。 このような場合は、DLL の DllGetActivationFactory と DllCanUnloadNow を手動で結合する必要があります。 これらのヘルパーにより、見かけ上の実行元のエラーが回避されて、それを行うのがはるかに簡単になります。
cppwinrt.exe
ツールの -lib
フラグを使って個々のライブラリに (winrt_xxx
ではなく) 独自のプリアンブルを提供し、各ライブラリの関数に個別の名前を付けて、明確に組み合わせられるようにすることもできます。
コルーチンのサポート
コルーチンのサポートは、自動的に組み込まれます。 これまでは、サポートは複数の場所に存在しており、制限が厳しすぎると考えられていました。 その後、V2.0 では一時的に winrt/coroutine.h
ヘッダー ファイルが必要でしたが、それはもう必要なくなっています。 Windows ランタイムの非同期インターフェイスは現在では手書きではなく生成されるようになったため、winrt/Windows.Foundation.h
に存在しています。 保守性とサポート性が高いとは別に、 resume_foreground などのコルーチン ヘルパーを特定の名前空間ヘッダーの末尾に取り付ける必要がなくなったことを意味します。 代わりに、もっと自然に依存関係を組み込むことができます。 これにより、resume_foreground は特定の Windows::UI::Core::CoreDispatcher での再開をサポートするだけでなく、特定の Windows::System::DispatcherQueue での再開もサポートできるようになりました。 以前は、定義は 1 つの名前空間にのみ存在できたため、両方ではなく、1 つのみをサポートできました。
DispatcherQueue サポートの例を次に示します。
...
#include <winrt/Windows.System.h>
using namespace Windows::System;
...
fire_and_forget Async(DispatcherQueueController controller)
{
bool queued = co_await resume_foreground(controller.DispatcherQueue());
assert(queued);
// This is just to simulate queue failure...
co_await controller.ShutdownQueueAsync();
queued = co_await resume_foreground(controller.DispatcherQueue());
assert(!queued);
}
コルーチン ヘルパーも [[nodiscard]]
で修飾されるようになったため、使いやすさが向上しています。 それらが動作するための co_await
を忘れた (または、必要であることを知らなかった) 場合、[[nodiscard]]
のため、このような誤りではコンパイラの警告が発生します。
直接 (スタック) 割り当ての診断でのヘルプ
投影されたクラス名と実装クラス名は (既定では) 同じであり、名前空間によってのみ異なるため、 make ファミリの ヘルパーを使用するのではなく、一方を間違えてスタックに誤って実装を作成する可能性があります。 これは、未解決の参照がまだ処理中にオブジェクトが破棄される可能性があるため、場合によっては診断が困難です。 デバッグ ビルドでは、アサーションによってこれが選択されるようになりました。 アサーションではコルーチン内のスタック割り当ては検出されませんが、それでもそのような誤りのほとんどを把握するのに役立ちます。
詳細については、「 直接割り当ての診断」を参照してください。
強化されたキャプチャ ヘルパーと可変個引数デリゲート
この更新では、プロジェクションが実行された型もサポートすることによって、キャプチャ ヘルパーに関する制限が修正されています。 これは、プロジェクションが実行された型を返すときに、Windows ランタイムの相互運用 API で発生することがあります。
この更新プログラムでは、可変 (Windows ランタイム以外) デリゲートを作成するときのget_strongとget_weakのサポートも追加されます。
遅延破棄および破棄中の安全な QI のサポート
ランタイム クラスのオブジェクトのデストラクターでは、参照カウントを一時的に増加させるメソッドが呼び出されることは珍しくありません。 参照カウントが 0 に戻ると、オブジェクトで 2 回目の破棄が行われます。 XAML アプリケーションでは、階層を上下にクリーンアップ実装を呼び出すために、デストラクターで QueryInterface (QI) を実行することが必要になる場合があります。 しかし、オブジェクトの参照カウントは既に 0 になっているので、その QI も参照カウントのバウンスを構成します。
この更新には、0 に達した後で再実行されないようにする、参照カウントのデバウンスのサポートが追加されています。それでも、破棄中に必要な一時的な QI は許可されます。 この手順は特定の XAML アプリケーション/コントロールでは避けられず、C++/WinRT はそれに対する回復力を持つようになっています。
実装型に静的 なfinal_release 関数を指定することで、破棄を延期できます。 オブジェクトへの最後の残りのポインター ( std::unique_ptr の形式) が final_releaseに渡されます。 その後、そのポインターの所有権を他のコンテキストに移動できます。 二重破棄をトリガーすることなくポインターに対して QI を行っても安全です。 ただし、オブジェクトを破棄する時点では、参照カウントに対する正味の変更が 0 になっている必要があります。
final_releaseの戻り値は、void
、IAsyncAction などの非同期操作オブジェクト、または winrt::fire_and_forget にすることができます。
struct Sample : implements<Sample, IStringable>
{
hstring ToString()
{
return L"Sample";
}
~Sample()
{
// Called when the unique_ptr below is reset.
}
static void final_release(std::unique_ptr<Sample> self) noexcept
{
// Move 'self' as needed to delay destruction.
}
};
次の例では、 MainPage が解放されると (最後の時間)、 final_release が呼び出されます。 この関数は (スレッド プールで) 5 秒間待機した後、ページの Dispatcher (QI/AddRef/Release が機能する必要があります) を使用して再開します。 その後、その UI スレッドでリソースをクリーンアップします。 最後に、 unique_ptrがクリアされ、 MainPage デストラクターが実際に呼び出されます。 そのデストラクターでも、
コルーチンとして final_release を実装する必要はありません。 しかし、それは動作し、非常に簡単に破棄を別のスレッドに移動できます。この例では、それが行われています。
struct MainPage : PageT<MainPage>
{
MainPage()
{
}
~MainPage()
{
DataContext(nullptr);
}
static IAsyncAction final_release(std::unique_ptr<MainPage> self)
{
co_await 5s;
co_await resume_foreground(self->Dispatcher());
co_await self->resource.CloseAsync();
// The object is destructed normally at the end of final_release,
// when the std::unique_ptr<MyClass> destructs. If you want to destruct
// the object earlier than that, then you can set *self* to `nullptr`.
self = nullptr;
}
};
詳細については、遅延破棄に関する記事を参照してください。
COM スタイルの単一インターフェイス継承に対するサポートの向上
Windows ランタイム プログラミングだけでなく、C++/WinRT は COM 専用 API の作成と使用にも使われます。 この更新では、インターフェイス階層が存在する COM サーバーを実装できるようになります。 これには Windows ランタイムには必要ありませんが、一部の COM 実装には必要です。
out
パラメーターの適切な処理
out
パラメーターの処理は難しいことがあります。Windows ランタイム配列の場合は特にそうです。 この更新では、out
のパラメーターと配列に関する誤りに対する C++/WinRT の信頼性と回復性がかなり高くなっています。それらのパラメーターが言語プロジェクションからのものか、生の ABI を使用している COM 開発者からのものか、変数の初期化が一貫していない誤りを誰が行ったかには関係ありません。 いずれの場合も、C++WinRT では、ABI に対するプロジェクションが実行された型の引き渡し (リソースの解放を記憶することで)、および ABI で到着したパラメーターのゼロ化またはクリアが、適切に処理されます。
イベントで確実に処理されるようになった無効なトークン
winrt::event 実装では、無効なトークン値 (配列に存在しない値) を使用して remove メソッドが呼び出されるケースが適切に処理されるようになりました。
コルーチンが戻る前にコルーチンのローカル変数が破棄される
コルーチン型を実装する従来の方法では、コルーチンの戻り/完了 後 (最終中断前ではなく) コルーチン内のローカル変数を破棄できる場合があります。 この問題を回避するためと他のメリットのため、待機処理の再開は最後の中断まで延期されるようになりました。
Windows SDK バージョン 10.0.17763.0 (Windows 10 バージョン 1809) での新機能と変更点
次の表では、Windows SDK バージョン 10.0.17763.0 (Windows 10 バージョン 1809) での C++/WinRT の新機能と変更点を示します。
新機能または変更された機能 | 詳細情報 |
---|---|
破壊的変更。 コンパイルで、C++/WinRT は Windows SDK からのヘッダーに依存しません。 | 以下の 「Windows SDK ヘッダー ファイルからの分離」を参照してください。 |
Visual Studio プロジェクト システムの形式が変更されました。 | 以下の「 C++/WinRT プロジェクトを新しいバージョンの Windows SDK に再ターゲットする方法」を参照してください。 |
Windows ランタイム関数にコレクション オブジェクトを渡すため、または独自のコレクション プロパティとコレクション型を実装するための、新しい関数と基底クラスがあります。 | C++/WinRTの |
{Binding} マークアップ拡張機能は、C++/WinRT ランタイム クラスと共に使用できます。 | 詳細とコード例については、「 データ バインディングの概要」を参照してください。 |
コルーチンの取り消しのサポートにより、取り消しコールバックを登録できます。 | 詳細とコード例については、「 非同期操作の取り消し」および「キャンセル コールバック」を参照してください。 |
メンバー関数を指し示すデリゲートを作成するとき、ハンドラーを登録する時点で、現在のオブジェクト (生の this ポインターのインスタンス) に対する強い参照または弱い参照を確立できます。 | 詳細とコード例については、「イベント処理デリゲートを使用してこの ポインター |
Visual Studio の C++ 標準への適合性が向上することによって発見されたバグが修正されました。 C++/WinRT の標準準拠の検証に対する LLVM および Clang ツールチェーンの利用も向上しています。 | 「新しいプロジェクトがコンパイルされない理由」で説明されている問題が発生しなくなりました。Visual Studio 2017 (バージョン 15.8.0 以降) と SDK バージョン 17134 を使用しています |
その他の変更点。
-
破壊的変更。
winrt::get_abi(winrt::hstring const>) は、
void*
ではなくHSTRING
を返すようになりました。static_cast<HSTRING>(get_abi(my_hstring));
を使って HSTRING を取得できます。 ABI の HSTRING との相互運用を参照してください。 -
破壊的変更。
winrt::put_abi(winrt::hstring&) は
void**
ではなくHSTRING*
を返すようになりました。reinterpret_cast<HSTRING*>(put_abi(my_hstring));
を使って HSTRING* を取得できます。 ABI の HSTRING との相互運用を参照してください。 -
破壊的変更。 HRESULT は winrt::hresult として投影されるようになりました。 HRESULT が必要な場合 (型チェックを行う場合、または型の特徴をサポートする場合)、
static_cast
をできます。 それ以外の場合、 winrt::hresult は、C++/WinRT ヘッダーを含める前にunknwn.h
を含める限り、HRESULT に変換されます。 -
破壊的変更。 GUID が winrt::guid として投影されるようになりました。 実装する API の場合は、GUID パラメーターに winrt::guid を使用する必要があります。 それ以外の場合、 winrt::guid は、C++/WinRT ヘッダーを含める前に
unknwn.h
を含める限り、GUID に変換されます。 ABI の GUID 構造体との相互運用を参照してください。 - 破壊的変更。 winrt::handle_type コンストラクターは明示的にすることで強化されました (不適切なコードを記述するのが難しくなりました)。 生のハンドル値を割り当てる必要がある場合は、代わりに handle_type::attach 関数 を呼び出します。
-
破壊的変更。
WINRT_CanUnloadNowとWINRT_GetActivationFactoryの署名が変更されました。 これらの関数は宣言しないでください。 代わりに、
winrt/base.h
をインクルードしてこれらの関数の宣言を含めます (いずれかの C++/WinRT Windows 名前空間ヘッダー ファイルをインクルードすると、自動的にインクルードされます)。 - winrt::clock 構造体において、from_FILETIME/to_FILETIMEは非推奨とされ、代わりにfrom_file_time/to_file_timeが推奨されます。
-
IBuffer パラメーターを必要とする簡略化された API。 ほとんどの API ではコレクションまたは配列が優先されますが、 しかし、IBufferに依存する API を簡単に呼び出
必要があると感じました。 この更新プログラムは、 IBuffer 実装の背後にあるデータへの直接アクセスを提供します。 実装の背後にあるデータに直接アクセスできます。 この規則により、慣例的に大文字で始まるメタデータの名前との競合も回避されます。 - コード生成の向上: コード サイズの削減、インライン化の向上、ファクトリ キャッシュの最適化に関するさまざまな改善。
- 不要な再帰を削除しました。 コマンド ラインで特定の
.winmd
ではなくフォルダーを参照するとき、cppwinrt.exe
ツールで.winmd
ファイルが再帰的に検索されなくなります。cppwinrt.exe
ツールでは重複の処理もいっそうインテリジェントになり、ユーザー エラーや不適切な形式の.winmd
ファイルに対する回復性が向上しています。 - 強化されたスマート ポインター。 以前は、新しい値を移動割り当てすると、イベント リボーカーは失効に失敗しました。 これは、スマート ポインター クラスが確実に自己割り当てを処理できない問題を明らかにするのに役立ちました。 winrt::com_ptr 構造体テンプレートにルート化されています。 winrt::com_ptr を修正しました。また、イベント リボーカーが移動セマンティクスを正しく処理するように修正され、割り当て時に失効するようになりました。
重要
バージョン 1.0.181002.2 とバージョン 1.0.190128.4 以降の両方で、 C++/WinRT Visual Studio 拡張機能 (VSIX) に対して重要な変更が行われました。 これらの変更の詳細と、それらが既存のプロジェクトに与える影響の詳細については、Visual Studio で C++/WinRT をサポート
Windows SDK ヘッダー ファイルからの分離
これは、コードに対する破壊的変更になる可能性があります。
C++/WinRT は、コンパイルで Windows SDK からのヘッダー ファイルに依存しなくなります。 C ランタイム ライブラリ (CRT) および C++ 標準テンプレート ライブラリ (STL) のヘッダー ファイルでも、Windows SDK ヘッダーがインクルードされなくなります。 それにより、標準への準拠が向上し、不注意による依存関係が回避され、防ぐ必要のあるマクロの数が大幅に減ります。
この独立性は、C++/WinRT の移植性と標準準拠の向上を意味し、クロスコンパイラおよびクロスプラットフォーム ライブラリになる可能性を促進します。 また、C++/WinRT ヘッダーがマクロに悪影響を及ぼさないことも意味します。
以前はプロジェクトへの Windows ヘッダーのインクルードを C++/WinRT に任せていた場合、自分でインクルードすることが必要になります。 いずれの場合も常に、依存するヘッダーを明示的にインクルードし、別のライブラリによって自動的にインクルードされるままにしないのが、ベスト プラクティスです。
現時点では、Windows SDK ヘッダー ファイルの分離に対する例外は、組み込み関数と数値だけです。 これらの最後に残っている依存関係に関する既知の問題はありません。
プロジェクトでは、必要に応じて、Windows SDK ヘッダーとの相互運用を再度有効にできます。 たとえば、( IUnknown にルート化された) COM インターフェイスを実装できます。 その例では、すべての C++/WinRT ヘッダーをインクルードする前に、unknwn.h
をインクルードします。 そのようにすると、C++/WinRT の基本ライブラリで、クラシック COM インターフェイスをサポートするためのさまざまなフックが有効になります。 コード例については、「 C++/WinRT を使用して COM コンポーネントを作成する」を参照してください。 同様に、呼び出そうとする型や関数が宣言されている他の Windows SDK ヘッダーを明示的にインクルードします。
C++/WinRT プロジェクトのターゲットを Windows SDK の後のバージョンに変更する方法
コンパイラとリンカーの問題が最も少なくなるようにプロジェクトのターゲットを変更する方法は、手間も最もかかります。 その方法では、新しいプロジェクトを (選択した Windows SDK のバージョンをターゲットにして) 作成した後、古いプロジェクトから新しいプロジェクトにファイルをコピーします。 古い .vcxproj
および .vcxproj.filters
ファイルには、コピーして Visual Studio のファイルに保存して追加するだけでよいセクションがあります。
ただし、Visual Studio でプロジェクトのターゲットを変更するには、他に 2 つの方法があります。
- プロジェクト プロパティ [全般>Windows SDK バージョン] に移動し、[ すべての構成] と [ すべてのプラットフォーム] を選択します。 Windows SDK のバージョンを対象とするバージョンに設定します。
- ソリューション エクスプローラーで、プロジェクト ノードを右クリックし、[プロジェクトの再ターゲット] をクリックし、ターゲットにするバージョンを選択して、[OK] をクリックします。
これら 2 つの方法のいずれかを使用した後にコンパイラまたはリンカーエラーが発生した場合は、もう一度ビルドする前に、ソリューション (Build>Clean Solution またはすべての一時フォルダーとファイルを手動で削除してみてください。
C++ コンパイラで "エラー C2039: 'IUnknown': is not a member of '`global namespace''" が生成される場合は、#include <unknwn.h>
を pch.h
ファイルの先頭に追加します (C++/WinRT ヘッダーを含める前)。
その後で、#include <hstring.h>
の追加も必要な場合があります。
C++ リンカーで "エラー LNK2019: 関数 _VSDesignerCanUnloadNow@0 で参照されている未解決の外部シンボル _WINRT_CanUnloadNow@0" が生成された場合は、#define _VSDESIGNER_DONT_LOAD_AS_DLL
ファイルにpch.h
を追加することで解決できます。