Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Com C++/WinRT, é possível chamar APIs do Windows Runtime utilizando tipos de dados do C++ padrão, incluindo alguns tipos de dados da biblioteca padrão do C++. Podes passar strings padrão para APIs (ver Gestão de strings em C++/WinRT), e podes passar listas de inicializadores e contentores padrão para APIs que esperam uma coleção semanticamente equivalente.
Veja também Passar parâmetros através da fronteira da ABI.
Listas de inicializadores padrão
Uma lista de inicializadores (std::initializer_list) é uma construção de Biblioteca Padrão em C++. Pode usar listas inicializadoras quando chama certos construtores e métodos do Windows Runtime. Por exemplo, pode chamar DataWriter::WriteBytes com um desses.
#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.
}
Há dois componentes envolvidos para que isto funcione. Primeiro, o método DataWriter::WriteBytes assume um parâmetro do tipo winrt::array_view.
void WriteBytes(winrt::array_view<uint8_t const> value) const
winrt::array_view é um tipo C++/WinRT personalizado que representa de forma segura uma série congênea de valores (está definido na biblioteca base C++/WinRT, que é %WindowsSdkDir%Include\<WindowsTargetPlatformVersion>\cppwinrt\winrt\base.h).
Em segundo lugar, o winrt::array_view tem um construtor de lista de inicializadores.
template <typename T> winrt::array_view(std::initializer_list<T> value) noexcept
Em muitos casos, pode escolher se quer ou não estar ciente do winrt::array_view na sua programação. Se optar por não estar ciente disso, então não terá código para alterar caso e quando um tipo equivalente aparecer na Biblioteca Padrão C++.
Pode passar uma lista de inicialização para uma API do Windows Runtime que espera um parâmetro de coleção. Veja-se como exemplo o StorageItemContentProperties::RetrievePropertiesAsync .
IAsyncOperation<IMap<winrt::hstring, IInspectable>> StorageItemContentProperties::RetrievePropertiesAsync(IIterable<winrt::hstring> propertiesToRetrieve) const;
Podes chamar essa API com uma lista de inicializadores assim.
IAsyncAction retrieve_properties_async(StorageFile const storageFile)
{
auto properties{ co_await storageFile.Properties().RetrievePropertiesAsync({ L"System.ItemUrl" }) };
}
Dois fatores estão em jogo aqui. Primeiro, a função chamada constrói um std::vector a partir da lista de inicialização (esta função chamada é assíncrona, por isso pode ficar na posse desse objeto, como é necessário). Em segundo lugar, o C++/WinRT associa de forma transparente (e sem introduzir cópias) std::vector a um parâmetro de coleção do Windows Runtime.
Matrizes e vetores padrão
Winrt::array_view também tem construtores de conversão a partir de STD::Vector e 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
Assim, podes chamar DataWriter::WriteBytes com um 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.
Ou com um 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 associa std::vector como parâmetro de coleção do Windows Runtime. Assim, podes passar um std::vector<winrt::hstring>, que será convertido na coleção do Windows Runtime apropriada para winrt::hstring. Há um detalhe extra a ter em conta se o chamado for assíncrono. Devido aos detalhes de implementação desse caso, terá de fornecer um valor r, por isso deve fornecer uma cópia ou um movimento do vetor. No exemplo de código abaixo, transferimos a propriedade do vetor para o objeto do tipo de parâmetro aceite pelo chamado assíncrono (e depois temos cuidado para não aceder vecH novamente depois de o movermos). Se quiseres saber mais sobre rvalores, vê Categorias de valores e referências a elas.
IAsyncAction retrieve_properties_async(StorageFile const storageFile, std::vector<winrt::hstring> vecH)
{
auto properties{ co_await storageFile.Properties().RetrievePropertiesAsync(std::move(vecH)) };
}
Mas não é possível passar um std::vector<std::wstring> quando é esperada uma coleção do Windows Runtime. Isto porque, tendo convertido para a coleção Windows Runtime apropriada de std::wstring, a linguagem C++ não irá então coagir o(s) parâmetro(s) de tipo dessa coleção. Consequentemente, o seguinte exemplo de código não compila (e a solução é passar um std::vector<winrt::hstring> em vez disso, como mostrado acima).
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 brutos e intervalos de ponteiros
Tendo em conta a ressalva de que um tipo equivalente pode existir no futuro na Biblioteca Padrão C++, também pode trabalhar diretamente com winrt::array_view se assim o desejar, ou for necessário.
winrt::array_view tem construtores de conversão a partir de um array bruto e de um intervalo de T* (apontadores para o 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.
Funções e operadores winrt::array_view
Uma série de construtores, operadores, funções e iteradores são implementados para winrt::array_view. Um winrt::array_view é um intervalo, pelo que o pode usar com forbaseado em intervalos ou com std::for_each.
Para mais exemplos e informações, consulte o tópico de referência da API winrt::array_view .
IVector<T> e construções de iteração padrão
SyndicationFeed.Items é um exemplo de API Windows Runtime que devolve uma coleção do tipo IVector<T> (projetada para C++/WinRT como winrt::Windows::Foundation::Collections::IVector<T>). Pode utilizar este tipo com construções de iteração padrão, como for baseadas em 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;
}
}
Corutinas C++ com APIs assíncronas do Windows Runtime
Pode continuar a usar a Parallel Patterns Library (PPL) ao chamar APIs assíncronas do Windows Runtime. No entanto, em muitos casos, as corrotinas C++ fornecem um idioma eficiente e mais fácil de codificar para interagir com objetos assíncronos. Para mais informações e exemplos de código, veja Concorrência e operações assíncronas com C++/WinRT.
APIs importantes
Tópicos relacionados
Windows developer