Standardní datové typy C++ a C++/WinRT

Pomocí C++/WinRT můžete volat rozhraní API prostředí Windows Runtime pomocí datových typů Standard C++, včetně některých datových typů standardní knihovny C++. Standardní řetězce můžete předávat rozhraním API (viz Zpracování řetězců v C++/WinRT) a seznamy inicializátorů a standardní kontejnery můžete předávat rozhraním API, která očekávají sémanticky ekvivalentní kolekci.

Viz také předávání parametrů přes rozhraní ABI.

Seznamy standardních inicializátorů

Seznam inicializátoru (std::initializer_list) je konstruktor standardní knihovny jazyka C++. Seznamy inicializátorů můžete použít při volání určitých konstruktorů a metod prostředí Windows Runtime. Můžete například volat DataWriter::WriteBytes s takovým objektem.

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

Aby to fungovalo, jsou potřeba dvě části. Nejprve metoda DataWriter::WriteBytes přebírá parametr typu winrt::array_view.

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

winrt::array_view je vlastní typ C++/WinRT, který bezpečně představuje souvislou řadu hodnot (je definována v základní knihovně C++/WinRT, což je %WindowsSdkDir%Include\<WindowsTargetPlatformVersion>\cppwinrt\winrt\base.h).

Za druhé, winrt::array_view má konstruktor pro seznam inicializátorů.

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

V mnoha případech si můžete vybrat, jestli si chcete být vědomi winrt::array_view v programování. Pokud se rozhodnete, že o tom nechcete vědět, nebudete mít žádný kód, který by se měl změnit, pokud a když se ve standardní knihovně C++ zobrazí ekvivalentní typ.

Seznam inicializátorů můžete předat rozhraní API prostředí Windows Runtime, které očekává parametr kolekce. Vezměte například StorageItemContentProperties::RetrievePropertiesAsync .

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

Toto rozhraní API můžete volat pomocí seznamu inicializátorů, například takto.

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

Tady jsou dva faktory. Nejprve volaná funkce vytvoří std::vector z inicializačního seznamu (tato volaná funkce je asynchronní, takže si tento objekt může převzít do vlastnictví, což také musí). Za druhé, C++/WinRT transparentně (a bez zavedení kopií) vytvoří vazbu std::vector jako parametr kolekce prostředí Windows Runtime.

Standardní pole a vektory

winrt::array_view má také konstruktory převodu z std::vector a 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

Místo toho byste mohli volat DataWriter::WriteBytes pomocí 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.

Nebo s polem 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 vytvoří vazbu std::vector jako parametr kolekce prostředí Windows Runtime. Můžete tedy předat std::vector<winrt::hstring>, který bude převeden na odpovídající kolekci prostředí prostředí Windows Runtime typu winrt::hstring. Pokud je volaný asynchronní, je potřeba mít na paměti další podrobnosti. Vzhledem k podrobnostem implementace tohoto případu budete muset zadat hodnotu rvalue, takže musíte zadat kopii nebo přesun vektoru. V následující ukázce kódu přeneseme vlastnictví vektoru na objekt typu parametru, který přijímá asynchronně volaná funkce (a pak si dáme pozor, abychom po přesunu k vecH znovu nepřistupovali). Pokud se chcete dozvědět více o hodnotách rvalue, přečtěte si téma Kategorie hodnot a odkazy na ně.

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

Nemůžete ale předat std::vector<std::wstring> tam, kde se očekává kolekce prostředí prostředí Windows Runtime. Je to proto, že po převedení na odpovídající kolekci prostředí Windows Runtime typu std::wstring už jazyk C++ nedokáže vynutit převod typových parametrů této kolekce. V důsledku toho se následující příklad kódu nezkompiluje (řešením je namísto toho předat std::vector<winrt::hstring>, jak je uvedeno výše).

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

Nezpracovaná pole a oblasti ukazatelů

S výhradou, že v budoucnu může ve standardní knihovně C++ existovat ekvivalentní typ, můžete také pracovat přímo s winrt::array_view, pokud se tak rozhodnete nebo to potřebujete.

winrt::array_view obsahuje konstruktory převodu z nezpracovaného pole a z rozsahu T* (ukazatele na typ prvku).

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.

Funkce a operátory typu winrt::array_view

Pro winrt::array_view je implementována celá řada konstruktorů, operátorů, funkcí a iterátorů. winrt::array_view je rozsah, takže ho můžete použít v cyklu založeném na rozsahu for, nebo s std::for_each.

Další příklady a informace najdete v referenčním tématu k rozhraní API winrt::array_view .

IVector<T> a standardní iterační konstrukce

SyndicationFeed.Items je příkladem rozhraní API prostředí Windows Runtime, které vrací kolekci typu IVector<T> (projektovaná do C++/WinRT jako winrt::Windows::Foundation::Collections::IVector<T>). Tento typ můžete použít se standardními konstrukcemi iterace, jako je například iterace založená na rozsahu 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;
    }
}

Koroutiny jazyka C++ s asynchronními rozhraními API prostředí Windows Runtime

Při volání asynchronních rozhraní API prostředí Windows Runtime můžete dál používat knihovnu PPL (Parallel Patterns Library). V mnoha případech však koroutiny jazyka C++ poskytují efektivní a snadněji zakódovaný idiom pro interakci s asynchronními objekty. Další informace a příklady kódu najdete v tématu Souběžnost a asynchronní operace s C++/WinRT.

Důležitá rozhraní API