Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Con C++/WinRT, puede llamar a Windows Runtime API mediante tipos de datos estándar de C++, incluidos algunos tipos de datos de la biblioteca estándar de C++. Puede pasar cadenas estándar a las API (consulte Control de cadenas en C++/WinRT) y puede pasar listas de inicializadores y contenedores estándar a las API que esperan una colección semánticamente equivalente.
Consulte también Pasar parámetros al límite de ABI.
Listas de inicializadores estándar
Una lista de inicializadores (std::initializer_list) es una construcción de biblioteca estándar de C++. Puede usar listas de inicializadores al llamar a determinados constructores y métodos de Windows Runtime. Por ejemplo, puede llamar a DataWriter::WriteBytes con este.
#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.
}
Hay dos piezas implicadas en la realización de este trabajo. En primer lugar, el método DataWriter::WriteBytes toma un parámetro de tipo winrt::array_view.
void WriteBytes(winrt::array_view<uint8_t const> value) const
winrt::array_view es un tipo personalizado de C++/WinRT que representa de forma segura una serie contigua de valores (se define en la biblioteca base de C++/WinRT, que es %WindowsSdkDir%Include\<WindowsTargetPlatformVersion>\cppwinrt\winrt\base.h).
En segundo lugar, winrt::array_view tiene un constructor initializer-list.
template <typename T> winrt::array_view(std::initializer_list<T> value) noexcept
En muchos casos, puedes elegir si tener en cuenta o no winrt::array_view al programar. Si decide no tenerlo en cuenta, no tendrá ningún código para cambiar si y cuando aparezca un tipo equivalente en la biblioteca estándar de C++.
Puede pasar una lista de inicializadores a una API de Windows Runtime que espera un parámetro de recopilación. Tome StorageItemContentProperties::RetrievePropertiesAsync por ejemplo.
IAsyncOperation<IMap<winrt::hstring, IInspectable>> StorageItemContentProperties::RetrievePropertiesAsync(IIterable<winrt::hstring> propertiesToRetrieve) const;
Puede llamar a esa API con una lista de inicializadores como esta.
IAsyncAction retrieve_properties_async(StorageFile const storageFile)
{
auto properties{ co_await storageFile.Properties().RetrievePropertiesAsync({ L"System.ItemUrl" }) };
}
Aquí intervienen dos factores. En primer lugar, la función llamada construye un std::vector a partir de la lista de inicialización (esta función llamada es asincrónica, por lo que puede asumir la propiedad de ese objeto, como debe hacer). En segundo lugar, C++/WinRT de forma transparente (y sin introducir copias) enlaza std::vector como parámetro de colección de Windows Runtime.
Matrices y vectores estándar
winrt::array_view también tiene constructores de conversión de std::vector y 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
Por lo tanto, podría llamar a DataWriter::WriteBytes con un 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.
O con un 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 enlaza std::vector como parámetro de colección de Windows Runtime. Por lo tanto, puedes pasar un std::vector<winrt::hstring> y se convertirá en la colección correspondiente de Windows Runtime de winrt::hstring. Hay un detalle adicional que se debe tener en cuenta si el destinatario es asincrónico. Debido a los detalles de implementación de ese caso, deberá proporcionar un valor r, por lo que debe proporcionar una copia o un movimiento del vector. En el ejemplo de código siguiente, movemos la propiedad del vector al objeto del tipo de parámetro aceptado por el destinatario asincrónico (y, a continuación, tenemos cuidado de no volver a acceder vecH después de moverlo). Si desea obtener más información sobre los valores r, consulte Categorías de valor y referencias a ellos.
IAsyncAction retrieve_properties_async(StorageFile const storageFile, std::vector<winrt::hstring> vecH)
{
auto properties{ co_await storageFile.Properties().RetrievePropertiesAsync(std::move(vecH)) };
}
Pero no se puede pasar un std::vector<std::wstring> cuando se espera una colección de Windows Runtime. Esto se debe a que, después de convertir a la colección de Windows Runtime adecuada de std::wstring, el lenguaje C++ no coerce los parámetros de tipo de esa colección. Por lo tanto, el siguiente ejemplo de código no se compilará (y la solución es pasar un std::vector<winrt::hstring> en su lugar, como se muestra anteriormente).
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.
}
Arrays sin procesar y rangos de punteros
Teniendo en cuenta la advertencia de que un tipo equivalente puede existir en el futuro en la biblioteca estándar de C++, también puede trabajar directamente con winrt::array_view si elige o necesita.
winrt::array_view tiene constructores de conversión a partir de un array sin procesar y de un intervalo de T* (punteros al tipo de elemento).
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.
Funciones y operadores winrt::array_view
Se implementan un host de constructores, operadores, funciones e iteradores para winrt::array_view. Un winrt::array_view es un rango, por lo que puedes usarlo en un bucle for basado en rangos o con std::for_each.
Para obtener más ejemplos e información, consulta el tema de referencia de api winrt::array_view .
IVector<T> y construcciones de iteración estándar
SyndicationFeed.Items es un ejemplo de una API de Windows Runtime que devuelve una colección de tipo IVector<T> (proyectada en C++/WinRT como winrt::Windows::Foundation::Collections::IVector<T>). Puede usar este tipo con constructos de iteración estándar, como forbasados en intervalos.
// 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;
}
}
Corrutinas de C++ con las API asíncronas de Windows Runtime
Puede seguir usando la Biblioteca de patrones paralelos (PPL) al llamar a las API de Windows Runtime asincrónicas. Sin embargo, en muchos casos, las corrutinas de C++ proporcionan una expresión codificada eficaz y más fácilmente para interactuar con objetos asincrónicos. Para obtener más información y ejemplos de código, consulta Operaciones asincrónicas y simultaneidad con C++/WinRT.