Passage de paramètres aux API projetées

Pour certains types, C++/WinRT fournit d’autres méthodes pour transmettre un paramètre à une API projetée. Ces classes acceptant les paramètres sont placées dans l’espace de noms winrt::param. Seul le code généré par C++/WinRT doit utiliser ces classes ; ne les utilisez pas dans vos propres fonctions et méthodes.

Important

Vous ne devez pas utiliser vous-même les types de l’espace de noms winrt::param. Ils sont au profit de la projection.

Certaines de ces options font la distinction entre les appels synchrones et asynchrones. La version des appels asynchrones prend généralement la propriété des données de paramètre pour s’assurer que les valeurs restent valides et inchangées tant que l’appel asynchrone n’est pas terminé. Notez toutefois que cette protection ne s’étend pas aux modifications apportées à la collection à partir d’un autre thread. Il est de votre responsabilité d’empêcher cela.

Options pour les paramètres de chaîne

winrt::param::hstring simplifie le passage de paramètres en tant que winrt::hstring. En plus de winrt::hstring, ces options sont également acceptées :

Alternative Notes
{} Une chaîne vide.
std::wstring_view L’affichage doit être suivie d’un terminateur null.
std::wstring
wchar_t const* Chaîne se terminant par une valeur null.

Vous ne pouvez pas passer nullptr pour représenter la chaîne vide. Utilisez plutôt L"" ou {}.

Le compilateur sait comment évaluer wcslen sur les littéraux de chaîne au moment de la compilation. Pour les littéraux, L"Name"sv et L"Name" sont donc équivalents.

Notez que les objets std::wstring_view ne se terminent pas par une valeur null. Toutefois, C++/WinRT nécessite que le caractère situé après la chaîne soit une valeur null. Si vous passez un std::wstring_view qui ne se termine pas par une valeur null, le processus s’arrête.

Options pour les paramètres itérables

winrt::param::iterable<T> et winrt::param::async_iterable<T> simplifient le passage de paramètres en tant que IIterable<T>.

Les collections Windows Runtime IVector<T> et IVectorView<T> prennent déjà en charge IIterable<T>. Les collections Windows Runtime IMap<K, V> et IMapView<K, V> prennent déjà en charge IIterable<IKeyValuePair<K, V>>.

Outre IIterable<T>, les options suivantes sont également acceptées. Notez que certaines options sont disponibles uniquement pour les méthodes synchrones.

Alternative Synchronisation Async Notes
std::vector<T> const& Oui Non
std::vector<T>&& Oui Oui Le contenu est déplacé dans une itérable temporaire.
std::initializer_list<T> Oui Oui La version asynchrone copie les éléments.
std::initializer_list<U> Oui Non U doit être convertible en T.
{ begin, end } Oui Non begin et end doivent être des itérateurs directs, et *begin doit être convertible en T.

Le double-itérateur fonctionne généralement dans les cas où vous avez une collection qui ne correspond à aucun des scénarios ci-dessus, à condition toutefois que vous puissiez l’itérer et produire des éléments pouvant être convertis en T. Par exemple, vous pouvez avoir un IVector<U> ou std::vector<U>, où U est convertible en T.

Dans l’exemple suivant, la méthode SetStorageItems attend un IIterable<IStorageItem>. Le modèle double-itérateur nous permet de passer d’autres types de collections.

// IVector of derived types.
winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Storage::StorageFile>
    storageFiles{ /* initialization elided */ };
dataPackage.SetStorageItems(storageFiles); // doesn't work
dataPackage.SetStorageItems({ storageFiles.begin(), storageFiles.end() }); // works

// Array of derived types.
std::array<winrt::Windows::Storage::StorageFile, 3>
    storageFiles{ /* initialization elided */ };
dataPackage.SetStorageItems(storageFiles); // doesn't work
dataPackage.SetStorageItems({ storageFiles.begin(), storageFiles.end() }); // works

Pour le cas de IIterable<IKeyValuePair<K, V>>, les alternatives suivantes sont acceptées. Notez que certaines options sont disponibles uniquement pour les méthodes synchrones.

Alternative Synchronisation Async Notes
std::map<K, V> const& Oui Non
std::map<K, V>&& Oui Oui Le contenu est déplacé vers une itérable temporaire.
std::unordered_map<K, V> const& Oui Non
std::unordered_map<K, V>&& Oui Oui Le contenu est déplacé vers une itérable temporaire.
std::initializer_list<std::pair<K, V>> Oui Oui La version asynchrone copie la liste dans une itérable temporaire.
{ begin, end } Oui Non begin et end doivent être des itérateurs directs, et begin->first et begin->second doivent être convertible en K et V, respectivement.

Options pour les paramètres de vue vectorielle

winrt::param::vector_view<T> et winrt::param::async_vector_view<T> simplifient le passage de paramètres en tant que IVectorView<T>.

Vous pouvez appeler IVector<T>::GetView pour obtenir un IVectorView<T> à partir d’un IVector<T>.

Outre IVectorView<T>, les options suivantes sont également acceptées. Notez que certaines options sont disponibles uniquement pour les méthodes synchrones.

Alternative Synchronisation Async Notes
std::vector<T> const& Oui Non
std::vector<T>&& Oui Oui Le contenu est déplacé dans un affichage temporaire.
std::initializer_list<T> Oui Oui La version asynchrone copie la liste dans un affichage temporaire.
{ begin, end } Oui Non begin et end doivent être des itérateurs directs, et *begin doit être convertible en T.

Là encore, la version double-itérateur peut être utilisée pour créer des affichages vectoriels hors des éléments qui ne correspondent pas à une option existante. L’affichage temporaire est plus efficace si les itérateurs begin et end sont des itérateurs d’accès aléatoire.

Options pour les paramètres d’affichage cartographique

winrt::param::map_view<T> et winrt::param::async_map_view<T> simplifient le passage de paramètres en tant que IMapView<T>.

Vous pouvez appeler IMap<K, V>::GetView pour obtenir un IMapView<K, V> à partir d’un IMap<K, V>.

Outre IMapView<K, V>, les options suivantes sont également acceptées. Notez que certaines options sont disponibles uniquement pour les méthodes synchrones.

Alternative Synchronisation Async Notes
std::map<K, V> const& Oui Non
std::map<K, V>&& Oui Oui Le contenu est déplacé dans un affichage temporaire.
std::unordered_map<K, V> const& Oui Non
std::unordered_map<K, V>&& Oui Oui Le contenu est déplacé dans un affichage temporaire.
std::initializer_list<std::pair<K, V>> Oui Oui Le contenu est copié dans un affichage temporaire. Les clés ne peuvent pas être dupliquées.

Options pour les paramètres de vecteur

winrt::param::vector<T> simplifie le passage de paramètres en tant que IVector<T>. Outre IVector<T>, ces options sont également acceptées :

Alternative Notes
std::vector<T>&& Le contenu est déplacé dans un vecteur temporaire. Les résultats ne sont pas redéplacés.
std::initializer_list<T>

Si la méthode mute le vecteur temporaire, ces modifications ne sont pas reflétées dans les paramètres d’origine. Pour observer les modifications, passez un IVector<T>.

Options pour les paramètres de carte

winrt::param::map<K, V> simplifie le passage de paramètres en tant que IMap<K, V>. Outre IMap<K, V>, ces options sont également acceptées :

Vous pouvez passer Notes
std::map<K, V>&& Le contenu est déplacé dans une carte temporaire. Les résultats ne sont pas redéplacés.
std::unordered_map<K, V>&& Le contenu est déplacé dans une carte temporaire. Les résultats ne sont pas redéplacés.
std::initializer_list<std::pair<K, V>>

Si la méthode mute la carte temporaire, ces modifications ne sont pas reflétées dans les paramètres d’origine. Pour observer les modifications, passez un IMap<K, V>.

Options pour les paramètres de tableau

winrt::array_view<T> n’est pas dans l’espace de noms winrt::param, mais il est utilisé pour les paramètres qui sont des tableaux de style C. En plus d’un array_view<T> explicite, ces options sont également acceptées :

Alternative Notes
{} Tableau vide.
U[] Tableau de style C, où U est convertible en T, et sizeof(U) == sizeof(T).
std::array<U, N> U est convertible en T, et sizeof(U) == sizeof(T).
std::vector<U> U est convertible en T, et sizeof(U) == sizeof(T).
{ begin, end } begin et end doivent être de type T*, représentant la plage [begin, end).
std::initializer_list<T>
std::span<U, N> U est convertible en T, et sizeof(U) == sizeof(T).

Consultez également le billet de blog The various patterns for passing C-style arrays across the Windows Runtime ABI boundary.