Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Avec C++/WinRT, vous pouvez appeler Windows Runtime API à l’aide de types de données C++ Standard, y compris certains types de données de bibliothèque standard C++. Vous pouvez passer des chaînes standard aux API (voir Gestion des chaînes en C++/WinRT) et passer des listes d’initialiseurs et des conteneurs standard aux API qui s’attendent à une collection sémantiquement équivalente.
Voir également Passage de paramètres dans la limite ABI.
Listes d’initialiseurs standard
Une liste d’initialiseurs (std ::initializer_list) est une construction de bibliothèque standard C++. Vous pouvez utiliser des listes d’initialiseurs lorsque vous appelez certains constructeurs et méthodes Windows Runtime. Par exemple, vous pouvez appeler DataWriter::WriteBytes avec l’un d’eux.
#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.
}
Il y a deux éléments impliqués dans la réalisation de ce travail. Tout d’abord, la méthode DataWriter ::WriteBytes prend un paramètre de type winrt ::array_view.
void WriteBytes(winrt::array_view<uint8_t const> value) const
winrt ::array_view est un type C++/WinRT personnalisé qui représente en toute sécurité une série de valeurs contiguë (elle est définie dans la bibliothèque de base C++/WinRT, qui est %WindowsSdkDir%Include\<WindowsTargetPlatformVersion>\cppwinrt\winrt\base.h).
Deuxièmement, winrt ::array_view a un constructeur de liste d’initialiseurs.
template <typename T> winrt::array_view(std::initializer_list<T> value) noexcept
Dans de nombreux cas, vous pouvez choisir d’avoir ou non à connaître winrt::array_view dans votre code. Si vous choisissez de ne pas le connaître, vous n’aurez pas de code à modifier si et quand un type équivalent apparaît dans la bibliothèque C++ Standard.
Vous pouvez passer une liste d’initialiseurs à une API Windows Runtime qui attend un paramètre de collection. Prenons StorageItemContentProperties ::RetrievePropertiesAsync , par exemple.
IAsyncOperation<IMap<winrt::hstring, IInspectable>> StorageItemContentProperties::RetrievePropertiesAsync(IIterable<winrt::hstring> propertiesToRetrieve) const;
Vous pouvez appeler cette API avec une liste d’initialiseurs comme suit.
IAsyncAction retrieve_properties_async(StorageFile const storageFile)
{
auto properties{ co_await storageFile.Properties().RetrievePropertiesAsync({ L"System.ItemUrl" }) };
}
Deux facteurs sont au travail ici. Tout d’abord, la fonction appelée construit un std::vector à partir de la liste d’initialisation (cette fonction appelée est asynchrone, elle peut donc prendre possession de cet objet, ce qu’elle doit faire). Deuxièmement, C++/WinRT associe de manière transparente (et sans introduire de copies) std::vector à un paramètre de collection Windows Runtime.
Tableaux et vecteurs standard
winrt ::array_view a également des constructeurs de conversion à partir de std ::vector et 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
Donc, vous pouvez à la place appeler DataWriter::WriteBytes avec 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.
Ou avec 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 associe std::vector à un paramètre de collection du Windows Runtime. Ainsi, vous pouvez passer un std::vector<winrt::hstring>, et il sera converti dans la collection Windows Runtime appropriée de winrt::hstring. Il existe un détail supplémentaire à garder à l’esprit si l’appelé est asynchrone. En raison des détails d’implémentation de ce cas, vous devez fournir une valeur rvalue. Vous devez donc fournir une copie ou un déplacement du vecteur. Dans l’exemple de code ci-dessous, nous allons déplacer la propriété du vecteur vers l’objet du type de paramètre accepté par l’appelé asynchrone (puis nous sommes prudents de ne plus y accéder vecH après le déplacement). Si vous souhaitez en savoir plus sur les valeurs rvalues, consultez les catégories valeur et les références à celles-ci.
IAsyncAction retrieve_properties_async(StorageFile const storageFile, std::vector<winrt::hstring> vecH)
{
auto properties{ co_await storageFile.Properties().RetrievePropertiesAsync(std::move(vecH)) };
}
Mais vous ne pouvez pas transmettre un std::vector<std::wstring> là où une collection Windows Runtime est attendue. Cela est dû au fait que, après avoir converti la collection d'Windows Runtime appropriée de std ::wstring, le langage C++ ne force pas ensuite le ou les paramètres de type de cette collection. Par conséquent, l’exemple de code suivant ne sera pas compilé (et la solution consiste à passer un std ::vector<winrt ::hstring> à la place, comme indiqué ci-dessus).
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.
}
Tableaux bruts et plages de pointeurs
N’oubliez pas qu’un type équivalent peut exister à l’avenir dans la bibliothèque C++ Standard, vous pouvez également travailler directement avec winrt ::array_view si vous choisissez, ou si vous avez besoin.
winrt ::array_view a des constructeurs de conversion à partir d’un tableau brut et d’une plage de T* (pointeurs vers le type d’élément).
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.
fonctions et opérateurs winrt ::array_view
De nombreux constructeurs, opérateurs, fonctions et itérateurs sont implémentés pour winrt::array_view. Un winrt::array_view est une plage. Vous pouvez donc l’utiliser dans une boucle forbasée sur une plage, ou avec std::for_each.
Pour plus d’exemples et d’informations, consultez la rubrique de référence sur l’API winrt ::array_view .
IVector<T> et les constructions d’itération standard
SyndicationFeed.Items est un exemple d’API Windows Runtime qui retourne une collection de types IVector<T> (projetés en C++/WinRT en tant que winrt ::Windows ::Foundation ::Collections ::IVector<T>). Vous pouvez utiliser ce type avec des structures d’itération standard, comme for basée sur une plage.
// 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;
}
}
Coroutines C++ avec des API de Windows Runtime asynchrones
Vous pouvez continuer à utiliser la bibliothèque de modèles parallèles (PPL) lors de l’appel d’API de Windows Runtime asynchrones. Toutefois, dans de nombreux cas, les coroutines C++ fournissent un idiome efficace et plus facilement codé pour interagir avec des objets asynchrones. Pour plus d’informations et des exemples de code, consultez Accès concurrentiel et opérations asynchrones avec C++/WinRT.
API importantes
Rubriques connexes
Windows developer