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

Dengan C++/WinRT, Anda dapat memanggil API Windows Runtime 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 API Windows Runtime 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, fungsi yang dipanggil membangun std::vector dari daftar inisialisasi (fungsi yang dipanggil ini bersifat asinkron, sehingga dapat memiliki objek tersebut, dan memang harus demikian). Kedua, C++/WinRT secara transparan (dan tanpa membuat salinan) menghubungkan 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 pada kasus itu, Anda perlu menyediakan sebuah rvalue, jadi Anda harus menyediakan salinan atau operasi pemindahan pada 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 mengoper std::vector<std::wstring> ketika 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 pointer

Dengan mengingat catatan bahwa jenis yang setara mungkin akan tersedia di Pustaka Standar C++ pada masa mendatang, Anda juga dapat menggunakan winrt::array_view secara langsung jika Anda mau atau perlu.

winrt::array_view memiliki konstruktor konversi dari array mentah, dan dari rentang T* (penunjuk ke tipe 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.

fungsi dan operator pada winrt::array_view

Sejumlah konstruktor, operator, fungsi, dan iterator diimplementasikan untuk winrt::array_view. winrt::array_view adalah sebuah rentang, sehingga Anda dapat menggunakannya dengan forberbasis rentang 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 API Windows Runtime yang mengembalikan kumpulan jenis IVector<T> (diproyeksikan ke dalam C++/WinRT sebagai winrt::Windows::Foundation::Collections::IVector<T>). Anda dapat menggunakan tipe ini dengan konstruksi perulangan standar, seperti for berbasis rentang.

// 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;
    }
}

Koroutin C++ 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