標準 C++ 資料類型與 C++/WinRTStandard C++ data types and C++/WinRT

使用 C++/WinRT,您可以標準 C++ 資料類型呼叫 Windows 執行階段 API,包括部分 C++ 標準程式庫資料類型。With C++/WinRT, you can call Windows Runtime APIs using Standard C++ data types, including some C++ Standard Library data types. 您可以將標準字串傳遞至 API (請參閱 C++/WinRT 中的字串處理),而且您可以將初始設定式清單和標準容器傳遞至預期語意相等集合的 API。You can pass standard strings to APIs (see String handling in C++/WinRT), and you can pass initializer lists and standard containers to APIs that expect a semantically equivalent collection.

另請參閱將參數傳入 ABI 界限Also see Passing parameters into the ABI boundary.

標準初始設定式清單Standard initializer lists

初始設定式清單 (std::initializer_list) 是 C++ 標準程式庫建構。An initializer list (std::initializer_list) is a C++ Standard Library construct. 您呼叫某些 Windows 執行階段建構函式與方法時,可以使用初始設定式清單。You can use initializer lists when you call certain Windows Runtime constructors and methods. 例如,您可以使用一個來呼叫 DataWriter::WriteBytesFor example, you can call DataWriter::WriteBytes with one.

#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.
}

有兩個項目參與進行這項工作。There are two pieces involved in making this work. 第一個,DataWriter::WriteBytes 方法採用類型 winrt::array_view 的參數。First, the DataWriter::WriteBytes method takes a parameter of type winrt::array_view.

void WriteBytes(winrt::array_view<uint8_t const> value) const

winrt::array_view 是自訂 C++/WinRT 類型,其安全地表示一連串的值 (在 C++/WinRT 基礎程式庫中定義它,也就是 %WindowsSdkDir%Include\<WindowsTargetPlatformVersion>\cppwinrt\winrt\base.h)。winrt::array_view is a custom C++/WinRT type that safely represents a contiguous series of values (it is defined in the C++/WinRT base library, which is %WindowsSdkDir%Include\<WindowsTargetPlatformVersion>\cppwinrt\winrt\base.h).

第二個,winrt::array_view 有初始設定式清單建構函式。Second, winrt::array_view has an initializer-list constructor.

template <typename T> winrt::array_view(std::initializer_list<T> value) noexcept

在許多情況下,您可以選擇是否要在您的程式設計中注意 winrt::array_viewIn many cases, you can choose whether or not to be aware of winrt::array_view in your programming. 如果您選擇「不」 注意它,如果以及當 C++ 標準程式庫中出現對等類型時,則不會變更任何程式碼。If you choose not to be aware of it then you won't have any code to change if and when an equivalent type appears in the C++ Standard Library.

您可以將一個初始設定式清單傳遞至需要一個集合參數的 Windows 執行階段 API。You can pass an initializer list to a Windows Runtime API that expects a collection parameter. StorageItemContentProperties::RetrievePropertiesAsync 為例。Take StorageItemContentProperties::RetrievePropertiesAsync for example.

IAsyncOperation<IMap<winrt::hstring, IInspectable>> StorageItemContentProperties::RetrievePropertiesAsync(IIterable<winrt::hstring> propertiesToRetrieve) const;

您可以像這樣使用初始設定式清單呼叫該 API。You can call that API with an initializer list like this.

IAsyncAction retrieve_properties_async(StorageFile const& storageFile)
{
    auto properties{ co_await storageFile.Properties().RetrievePropertiesAsync({ L"System.ItemUrl" }) };
}

此處執行兩個因素。Two factors are at work here. 第一個,被呼叫者從初始設定式清單建構一個 std::vector (此被呼叫者必須為非同步,如此才能有該物件)。First, the callee constructs a std::vector from the initializer list (this callee is asynchronous, so it's able to own that object, which it must). 第二個,C++/WinRT 明確地 (且不使用複製) 繫結 std::vector 做為 Windows 執行階段集合參數。Second, C++/WinRT transparently (and without introducing copies) binds std::vector as a Windows Runtime collection parameter.

標準陣列和向量Standard arrays and vectors

winrt::array_view 也有s conversion constructors from std::vectorstd::array 的轉換建構函式。winrt::array_view also has conversion constructors from std::vector and 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::WriteBytesSo, you could instead call DataWriter::WriteBytes with a std::vector.

std::vector<byte> theVector{ 99, 98, 97 };
dataWriter.WriteBytes(theVector); // theVector is converted to a winrt::array_view before being passed to WriteBytes.

或使用 std::arrayOr with a 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 執行階段集合參數。C++/WinRT binds std::vector as a Windows Runtime collection parameter. 因此,您可以傳遞 std::vector<winrt::hstring> ,並將它轉換為適當的 winrt::hstring Windows 執行階段集合。So, you can pass a std::vector<winrt::hstring>, and it will be converted to the appropriate Windows Runtime collection of winrt::hstring. 如果被呼叫者為非同步,則必須特別注意更多細節。There's an extra detail to bear in mind if the callee is asynchronous. 由於這種情況有實作細節必須注意,因此您必須提供 rvalue,此時您必須提供向量的複製或移動。Due to the implementation details of that case, you'll need to provide an rvalue, so you must provide a copy or a move of the vector. 在下列程式碼範例中,我們將向量的擁有權移動至非同步被呼叫者接受的參數類型物件 (移動後不可再次存取 vecH)。In the code example below, we move ownership of the vector to the object of the parameter type accepted by the async callee (and then we're careful not to access vecH again after moving it). 如果您想要深入了解 rvalue,請參閱值類別和它們的參考If you want to know more about rvalues, see Value categories, and references to them.

IAsyncAction retrieve_properties_async(StorageFile const storageFile, std::vector<winrt::hstring> vecH)
{
    auto properties{ co_await storageFile.Properties().RetrievePropertiesAsync(std::move(vecH)) };
}

但您無法傳遞 std::vector<std::wstring> 其中預期一個 Windows 執行階段集合。But you can't pass a std::vector<std::wstring> where a Windows Runtime collection is expected. 這是因為發生轉換至適當的 std::wstring Windows 執行階段集合,C++ 語言不會強制該集合的類型參數。This is because, having converted to the appropriate Windows Runtime collection of std::wstring, the C++ language won't then coerce that collection's type parameter(s). 因此,下列程式碼範例不會編譯 (而且解決方法是改為傳遞 std::vector<winrt::hstring> ,如上所示)。Consequently, the following code example won't compile (and the solution is to pass a std::vector<winrt::hstring> instead, as shown above).

IAsyncAction retrieve_properties_async(StorageFile const& storageFile, std::vector<std::wstring> const& vecW)
{
    auto properties{ co_await storageFile.Properties().RetrievePropertiesAsync(std::move(vecW)) }; // error! Can't convert from vector of wstring to async_iterable of hstring.
}

原始陣列和指標範圍Raw arrays, and pointer ranges

請記住,在之後 C++ 標準程式庫中可能會存在一個對等項目,您也可以直接使用 winrt::array_view,如果您選擇如此,或者需要這麼做的話。Bearing in mind the caveat that an equivalent type may exist in the future in the C++ Standard Library, you can also work directly with winrt::array_view if you choose to, or need to.

winrt::array_view 已從原始陣列,以及從 T* 的範圍 (指向元素類型) 轉換建構函式。winrt::array_view has conversion constructors from a raw array, and from a range of T* (pointers to the element type).

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 functions and operators

winrt::array_view 實作許多建構函式、運算子、函式和迭代器。A host of constructors, operators, functions, and iterators are implemented for winrt::array_view. winrt::array_view 是一個範圍,讓您可以有範圍基礎 for,或有 std::for_each 來使用它。A winrt::array_view is a range, so you can use it with range-based for, or with std::for_each.

如需詳細範例和資訊,請參閱 winrt::array_view API 參考主題。For more examples and info, see the winrt::array_view API reference topic.

IVector<T> 和標準反覆運算建構IVector<T> and standard iteration constructs

SyndicationFeed.Items 是一種 Windows 執行階段 API,會傳回類型 IVector<T> 的集合 (投射至 C++/WinRT 成為 winrt::Windows::Foundation::Collections::IVector<T> )。SyndicationFeed.Items is an example of a Windows Runtime API that returns a collection of type IVector<T> (projected into C++/WinRT as winrt::Windows::Foundation::Collections::IVector<T>). 您可以搭配標準反覆運算建構 (例如範圍架構的 for) 使用此類型。You can use this type with standard iteration constructs, such as range-based 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++ 協同程式C++ coroutines with asynchronous Windows Runtime APIs

您呼叫非同步 Windows 執行階段 API 時,可以繼續使用平行模式程式庫 (PPL)You can continue to use the Parallel Patterns Library (PPL) when calling asynchronous Windows Runtime APIs. 不過,在許多情況下,對於與非同步物件互動,C++ 協同程式提供有效率且撰寫程式碼更容易的慣用語。However, in many cases, C++ coroutines provide an efficient and more easily-coded idiom for interacting with asynchronous objects. 如需詳細資訊和程式碼範例,請參閱使用 C++/WinRT 的並行和非同步作業For more info, and code examples, see Concurrency and asynchronous operations with C++/WinRT.

重要 APIImportant APIs