C++/WinRT では、一部の C++ 標準ライブラリ データ型を含む、標準 C++ データ型を使用して Windows ランタイム API を呼び出すことができます。 標準文字列を API に渡すことができます ( C++/WinRT での文字列処理を参照)、初期化子リストと標準コンテナーを、意味的に同等のコレクションを必要とする API に渡すことができます。
ABI 境界へのパラメーターの受け渡しも参照してください。
標準初期化子リスト
初期化子リスト (std::initializer_list) は C++ 標準ライブラリコンストラクトです。 初期化子リストは、特定のWindows ランタイムコンストラクターとメソッドを呼び出すときに使用できます。 たとえば、 DataWriter::WriteBytes を 1 つで呼び出すことができます。
#include <winrt/Windows.Storage.Streams.h>
using namespace winrt::Windows::Storage::Streams;
int main()
{
winrt::init_apartment();
InMemoryRandomAccessStream stream;
DataWriter dataWriter{stream};
dataWriter.WriteBytes({ 99, 98, 97 }); // the initializer list is converted to a winrt::array_view before being passed to WriteBytes.
}
この作品の制作には、2つの要素があります。 まず、 DataWriter::WriteBytes メソッドは winrt::array_view 型のパラメーターを受け取ります。
void WriteBytes(winrt::array_view<uint8_t const> value) const
winrt::array_view は、連続する一連の値を安全に表すカスタム C++/WinRT 型です (これは、 %WindowsSdkDir%Include\<WindowsTargetPlatformVersion>\cppwinrt\winrt\base.hされている C++/WinRT 基本ライブラリで定義されています)。
次に、winrt::array_view は初期化子リスト コンストラクターを備えています。
template <typename T> winrt::array_view(std::initializer_list<T> value) noexcept
多くの場合、プログラミングで winrt::array_view を認識するかどうかを選択できます。 それを意識しないことを選べば、将来 C++ 標準ライブラリに同等の型が追加されても、変更すべきコードはありません。
初期化子リストは、コレクション パラメーターを必要とするWindows ランタイム API に渡すことができます。 たとえば 、StorageItemContentProperties::RetrievePropertiesAsync を取得します。
IAsyncOperation<IMap<winrt::hstring, IInspectable>> StorageItemContentProperties::RetrievePropertiesAsync(IIterable<winrt::hstring> propertiesToRetrieve) const;
このような初期化子リストを使用して、その API を呼び出すことができます。
IAsyncAction retrieve_properties_async(StorageFile const storageFile)
{
auto properties{ co_await storageFile.Properties().RetrievePropertiesAsync({ L"System.ItemUrl" }) };
}
ここでは、2 つの要因が動作しています。 まず、呼び出し先は初期化子リストから std::vector を生成します(この呼び出し先は非同期で動作するため、そのオブジェクトを自ら保持でき、実際にそうする必要があります)。 次に、C++/WinRT は透過的に (コピーを導入せずに) std::vector をWindows ランタイムコレクション パラメーターとしてバインドします。
標準の配列とベクター
winrt::array_viewには、std::vector と std::array からの変換コンストラクターもあります。
template <typename C, size_type N> winrt::array_view(std::array<C, N>& value) noexcept
template <typename C> winrt::array_view(std::vector<C>& vectorValue) noexcept
そのため、代わりに std::vector を使用して DataWriter::WriteBytes を呼び出します。
std::vector<byte> theVector{ 99, 98, 97 };
dataWriter.WriteBytes(theVector); // theVector is converted to a winrt::array_view before being passed to WriteBytes.
または std::array を使用します。
std::array<byte, 3> theArray{ 99, 98, 97 };
dataWriter.WriteBytes(theArray); // theArray is converted to a winrt::array_view before being passed to WriteBytes.
C++/WinRT は、std::vector をWindows ランタイムコレクション パラメーターとしてバインドします。 したがって、std::vector<winrt::hstring> を渡すと、winrt::hstring の適切なWindows ランタイム コレクションに変換されます。 呼び出し先が非同期の場合は、注意が必要な追加の詳細があります。 そのケースの実装上の詳細により、rvalue を渡す必要があるため、ベクターのコピーまたはムーブを渡さなければなりません。 次のコード例では、ベクターの所有権を非同期呼び出し先が受け入れるパラメーター型のオブジェクトに移動します (その後、移動後に vecH に再度アクセスしないように注意します)。 右辺値についてさらに詳しく知りたい場合は、「値のカテゴリとその参照」を参照してください。
IAsyncAction retrieve_properties_async(StorageFile const storageFile, std::vector<winrt::hstring> vecH)
{
auto properties{ co_await storageFile.Properties().RetrievePropertiesAsync(std::move(vecH)) };
}
ただし、Windows ランタイム コレクションが必要とされる場所に std::vector<std::wstring> を渡すことはできません。 これは、std::wstring の適切なWindows ランタイム コレクションに変換された場合、C++ 言語はそのコレクションの型パラメーターを強制しないためです。 その結果、次のコード例はコンパイルされません (また、上記のように 、代わりに std::vector<winrt::hstring> を渡します)。
IAsyncAction retrieve_properties_async(StorageFile const storageFile, std::vector<std::wstring> vecW)
{
auto properties{ co_await storageFile.Properties().RetrievePropertiesAsync(std::move(vecW)) }; // error! Can't convert from vector of wstring to async_iterable of hstring.
}
生の配列とポインターの範囲
C++ 標準ライブラリで同等の型が将来存在する可能性があることを念頭に置いて、 winrt::array_view を選択した場合、または必要に応じて直接操作することもできます。
winrt::array_view には、生の配列と T* の範囲 (要素型へのポインター) からの変換コンストラクターがあります。
using namespace winrt;
...
byte theRawArray[]{ 99, 98, 97 };
array_view<byte const> fromRawArray{ theRawArray };
dataWriter.WriteBytes(fromRawArray); // the winrt::array_view is passed to WriteBytes.
array_view<byte const> fromRange{ theArray.data(), theArray.data() + 2 }; // just the first two elements.
dataWriter.WriteBytes(fromRange); // the winrt::array_view is passed to WriteBytes.
winrt::array_view 関数と演算子
コンストラクター、演算子、関数、反復子のホストは、 winrt::array_view 用に実装されます。
winrt::array_view は範囲であるため、範囲ベースのforまたは std::for_each で使用できます。
詳細な例と情報については、 winrt::array_view API リファレンス トピックを参照してください。
IVector<T> および標準反復コンストラクト
SyndicationFeed.Items は、IVector<T> 型のコレクションを返すWindows ランタイム API の例です (winrt::Windows::Foundation::Collections::IVector<T> として C++/WinRT に投影されます)。 この型は、範囲ベースの forなど、標準の反復コンストラクトで使用できます。
// main.cpp
#include "pch.h"
#include <winrt/Windows.Web.Syndication.h>
#include <iostream>
using namespace winrt;
using namespace Windows::Web::Syndication;
void PrintFeed(SyndicationFeed const& syndicationFeed)
{
for (SyndicationItem const& syndicationItem : syndicationFeed.Items())
{
std::wcout << syndicationItem.Title().Text().c_str() << std::endl;
}
}
非同期Windows ランタイム API を使用した C++ コルーチン
非同期Windows ランタイム API を呼び出すときは、並列パターン ライブラリ (PPL) を引き続き使用できます。 ただし、多くの場合、C++ コルーチンは、非同期オブジェクトと対話するための効率的で簡単にコーディングされたイディオムを提供します。 詳細とコード例については、「 C++/WinRT を使用したコンカレンシーと非同期操作」を参照してください。
重要な API
関連トピック
Windows developer