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, puedes llamar a DataWriter::WriteBytes con una lista.
#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, el destinatario construye un std:: vector desde la lista de inicializadores (este destinatario es asincrónico, lo que quiere decir que puede y debe poseer dicho objeto). 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á a la colección adecuada de Windows Runtime de winrt::hstring. Hay un detalle adicional que hay que 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 de tipo de parámetro aceptado por el destinatario asincrónico. Después, tenemos cuidado de no acceder a vecH después de moverla. 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 puedes pasar un std:: vector<std:: wstring> donde se espera una colección de Windows Runtime. Esto se debe a que, al haber convertido a la colección adecuada de Windows Runtime de std:: wstring, el lenguaje de C++ no forzará el o los parámetro/s de tipo de dicha 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 los constructores de conversión de una matriz sin procesar y de un intervalo de T* (punteros para el 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.
winrt::array_view es un intervalo, así que puedes usarlo con for basado en intervalos 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.