Jenis data C++ standar dan C++/WinRT

Dengan C++/WinRT, Anda dapat memanggil WINDOWS Runtime API menggunakan jenis data C++ Standar, termasuk beberapa jenis data Pustaka Standar C++. Anda dapat meneruskan string standar ke API (lihat Penanganan string di C++/WinRT), dan Anda dapat meneruskan daftar inisialisasi dan kontainer standar ke API yang mengharapkan koleksi yang setara secara semantik.

Lihat juga Meneruskan parameter ke dalam batas ABI.

Daftar penginisialisasi standar

Daftar penginisialisasi (std::initializer_list) adalah konstruksi Pustaka Standar C++. Anda dapat menggunakan daftar penginisialisasi saat memanggil konstruktor dan metode Windows Runtime tertentu. Misalnya, Anda dapat memanggil DataWriter::WriteBytes dengan satu.

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

Ada dua bagian yang terlibat dalam membuat pekerjaan ini. Pertama, metode DataWriter::WriteBytes mengambil parameter jenis winrt::array_view.

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

winrt::array_view adalah jenis C++/WinRT kustom yang dengan aman mewakili serangkaian nilai yang berdekatan (ditentukan dalam pustaka dasar C++/WinRT, yaitu %WindowsSdkDir%Include\<WindowsTargetPlatformVersion>\cppwinrt\winrt\base.h).

Kedua, winrt::array_view memiliki konstruktor initializer-list.

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

Dalam banyak kasus, Anda dapat memilih apakah akan menyadari winrt::array_view dalam pemrograman Anda atau tidak. Jika Anda memilih untuk tidak menyadarinya maka Anda tidak akan memiliki kode apa pun untuk diubah jika dan ketika jenis yang setara muncul di Pustaka Standar C++.

Anda dapat meneruskan daftar penginisialisasi ke WINDOWS Runtime API yang mengharapkan parameter koleksi. Ambil StorageItemContentProperties::RetrievePropertiesAsync misalnya.

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

Anda dapat memanggil API tersebut dengan daftar inisialisasi seperti ini.

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

Dua faktor sedang bekerja di sini. Pertama, callee membuat std::vector dari daftar initializer (callee ini asinkron, sehingga dapat memiliki objek tersebut, yang harus dimilikinya). Kedua, C++/WinRT secara transparan (dan tanpa memperkenalkan salinan) mengikat std::vector sebagai parameter koleksi Windows Runtime.

Array dan vektor standar

winrt::array_view juga memiliki konstruktor konversi dari std::vector dan 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

Jadi, Anda dapat memanggil DataWriter::WriteBytes dengan 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.

Atau dengan 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 mengikat std::vector sebagai parameter koleksi Windows Runtime. Jadi, Anda dapat meneruskan std::vector<winrt::hstring>, dan itu akan dikonversi ke koleksi Windows Runtime winrt::hstring yang sesuai. Ada detail tambahan yang perlu diingat jika penerima panggilan tidak sinkron. Karena detail implementasi kasus tersebut, Anda harus memberikan rvalue, jadi Anda harus memberikan salinan atau pemindahan vektor. Dalam contoh kode di bawah ini, kami memindahkan kepemilikan vektor ke objek jenis parameter yang diterima oleh penerima asinkron (dan kemudian kami berhati-hati untuk tidak mengaksesnya vecH lagi setelah memindahkannya). Jika Anda ingin mengetahui selengkapnya tentang rvalue, lihat Kategori nilai, dan referensinya.

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

Tetapi Anda tidak dapat meneruskan std::vector<std::wstring> di mana koleksi Windows Runtime diharapkan. Ini karena, setelah dikonversi ke koleksi Windows Runtime std ::wstring yang sesuai, bahasa C++ tidak akan memaksa parameter jenis koleksi tersebut. Akibatnya, contoh kode berikut tidak akan dikompilasi (dan solusinya adalah meneruskan std::vector<winrt::hstring> sebagai gantinya, seperti yang ditunjukkan di atas).

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

Array mentah, dan rentang penunjuk

Mengingat peringatan bahwa jenis yang setara mungkin ada di masa depan di Pustaka Standar C++, Anda juga dapat bekerja langsung dengan winrt::array_view jika Anda memilih, atau perlu.

winrt::array_view memiliki konstruktor konversi dari array mentah, dan dari berbagai T* (pointer ke jenis elemen).

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 fungsi dan operator

Sejumlah konstruktor, operator, fungsi, dan iterator diimplementasikan untuk winrt::array_view. Winrt::array_view adalah rentang, sehingga Anda dapat menggunakannya dengan berbasis forrentang , atau dengan std::for_each.

Untuk contoh dan info selengkapnya, lihat topik referensi API winrt::array_view .

IVector<T> dan konstruksi iterasi standar

SyndicationFeed.Items adalah contoh WINDOWS Runtime API yang mengembalikan kumpulan jenis IVector<T> (diproyeksikan ke dalam C++/WinRT sebagai winrt::Windows::Foundation::Collections::IVector<T).> Anda dapat menggunakan jenis ini dengan konstruksi iterasi standar, seperti berbasis forrentang .

// 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 dengan API Windows Runtime asinkron

Anda dapat terus menggunakan Pustaka Pola Paralel (PPL) saat memanggil API Windows Runtime asinkron. Namun, dalam banyak kasus, coroutine C++ memberikan idiom yang efisien dan lebih mudah dikodekan untuk berinteraksi dengan objek asinkron. Untuk informasi selengkapnya, dan contoh kode, lihat Operasi konkurensi dan asinkron dengan C++/WinRT.

API penting