Standaard C++ gegevenstypen en C++/WinRT

Met C++/WinRT kunt u Windows Runtime API's aanroepen met behulp van Standard C++-gegevenstypen, waaronder enkele C++ Standard Library-gegevenstypen. U kunt standaardtekenreeksen doorgeven aan API's (zie De verwerking van tekenreeksen in C++/WinRT) en u kunt initialisatielijsten en standaardcontainers doorgeven aan API's die een semantisch equivalente verzameling verwachten.

Zie ook Parameters doorgeven over de ABI-grens.

Standaard initialisatielijsten

Een initialisatielijst (std::initializer_list) is een C++-standaardbibliotheekconstructie. U kunt initialisatielijsten gebruiken wanneer u bepaalde Windows Runtime constructors en methoden aanroept. U kunt bijvoorbeeld DataWriter::WriteBytes met één aanroepen.

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

Er zijn twee onderdelen betrokken bij het maken van dit werk. Eerst gebruikt de methode DataWriter::WriteBytes een parameter van het type winrt::array_view.

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

winrt::array_view is een aangepast C++/WinRT-type dat veilig een aaneengesloten reeks waarden vertegenwoordigt (deze is gedefinieerd in de C++/WinRT-basisbibliotheek, dat wil %WindowsSdkDir%Include\<WindowsTargetPlatformVersion>\cppwinrt\winrt\base.hzeggen).

Ten tweede heeft winrt::array_view een initialisatielijstconstructor.

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

In veel gevallen kunt u kiezen of u al dan niet op de hoogte wilt zijn van winrt::array_view in uw programmering. Als u ervoor kiest om er geen rekening mee te houden, hebt u geen code om te wijzigen als en wanneer een equivalent type wordt weergegeven in de C++-standaardbibliotheek.

U kunt een initialisatielijst doorgeven aan een Windows Runtime-API die een verzamelingsparameter verwacht. Neem bijvoorbeeld StorageItemContentProperties::RetrievePropertiesAsync .

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

U kunt die API aanroepen met een initialisatielijst zoals deze.

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

Er zijn hier twee factoren aan het werk. Eerst construeert de callee een std::vector op basis van de initialisatielijst (deze callee is asynchroon, dus kan hij eigenaar zijn van dat object, wat ook nodig is). Ten tweede verbindt C++/WinRT transparant (en zonder introductie van kopieën) std::vector als een Windows Runtime verzamelingsparameter.

Standaardarrays en vectoren

winrt::array_view heeft ook conversieconstructors van std::vector en 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

U kunt in plaats daarvan DataWriter::WriteBytes aanroepen met een 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.

Of met een 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 bindt std::vector als een Windows Runtime verzamelingsparameter. U kunt dus een std::vector<winrt::hstring> doorgeven en deze wordt geconverteerd naar de juiste Windows Runtime verzameling winrt::hstring. Er is een extra detail om rekening mee te houden als de gebruiker asynchroon is. Vanwege de implementatiedetails van dat geval moet u een rvalue opgeven, dus u moet een kopie of verplaatsing van de vector opgeven. In het onderstaande codevoorbeeld dragen we de eigendom van de vector over aan het object van het parametertype dat door de asynchrone aangeroepen functie wordt geaccepteerd (en daarna zorgen we ervoor dat we vecH niet opnieuw benaderen nadat het is verplaatst). Als u meer wilt weten over rvalues, raadpleegt u waardecategorieën en verwijzingen naar deze categorieën.

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

Maar u kunt geen std::vector<std::wstring> doorgeven op een plek waar een Windows Runtime-verzameling wordt verwacht. Dit komt doordat de C++-taal, nadat deze is geconverteerd naar de juiste Windows Runtime-verzameling van std::wstring, vervolgens de typeparameter(s) van die verzameling niet impliciet zal converteren. Daarom wordt het volgende codevoorbeeld niet gecompileerd (en de oplossing is om in plaats daarvan een std::vector<winrt::hstring> door te geven, zoals hierboven wordt weergegeven).

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

Onbewerkte matrices en aanwijzerbereiken

Houd er rekening mee dat een equivalent type in de toekomst in de C++ Standard-bibliotheek kan bestaan, u kunt ook rechtstreeks met winrt::array_view werken als u dat wilt of nodig hebt.

winrt::array_view heeft conversieconstructors van een onbewerkte matrix en van een bereik van T* (aanwijzers naar het elementtype).

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 functies en operatoren

Een host van constructors, operators, functies en iterators worden geïmplementeerd voor winrt::array_view. Een winrt::array_view is een reeks, dus u kunt deze gebruiken met een op een reeks gebaseerde for, of met std::for_each.

Zie het naslagonderwerp winrt::array_view API voor meer voorbeelden en informatie.

IVector<T> en standaard iteratieconstructies

SyndicationFeed.Items is een voorbeeld van een Windows Runtime-API die een verzameling van het type IVector<T> retourneert (geprojecteerd in C++/WinRT als winrt::Windows::Foundation::Collections::IVector<T>). U kunt dit type gebruiken met standaard iteratieconstructies, zoals op bereik gebaseerd 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;
    }
}

C++ coroutines in combinatie met de asynchrone Windows Runtime-API’s

U kunt de PPL (Parallel Patterns Library) blijven gebruiken bij het aanroepen van asynchrone Windows Runtime API's. In veel gevallen bieden C++-coroutines echter een efficiëntere en eenvoudiger gecodeerde idioom voor interactie met asynchrone objecten. Zie Gelijktijdigheid en asynchrone bewerkingen met C++/WinRT voor meer informatie en codevoorbeelden.

Belangrijke API's