Pasar parámetros a las API proyectadas

Para determinados tipos, C++/WinRT proporciona métodos alternativos para pasar un parámetro a una API proyectada. Estas clases de aceptación de parámetros se colocan en el espacio de nombres winrt::param. Solo el código generado por C++/WinRT debería usar estas clases. No las use en sus propias funciones y métodos.

Importante

No debes usar los tipos en el espacio de nombres winrt::param tú mismo. Esto es porque se usarán en beneficio de la proyección.

Algunas de estas alternativas distinguen entre llamadas sincrónicas y asincrónicas. La versión de las llamadas asincrónicas normalmente toma el control de los datos del parámetro para asegurarse de que los valores sigan siendo válidos y no tengan cambios hasta que se completa la llamada asincrónica. Sin embargo, tenga en cuenta que esta protección no se extiende a los cambios en la colección desde otro subproceso. Prevenir eso es tu responsabilidad.

Alternativas para parámetros de cadena

winrt::param::hstring simplifica el paso de parámetros como winrt::hstring. Además de winrt::hstring, estas alternativas también se aceptan:

Alternativa Notas
{} Una cadena vacía.
std::wstring_view La vista debe ir seguida de un terminador NULL.
std::wstring
wchar_t const* Una cadena terminada en null.

No se puede pasar nullptr para representar la cadena vacía. En su lugar, use L"" o {}.

El compilador sabe cómo evaluar wcslen en valores literales de cadena durante el tiempo de compilación. Por tanto, L"Name"sv y L"Name" son equivalentes para los valores literales.

Tenga en cuenta que los objetos std::wstring_view no terminan en NULL, pero C++/WinRT requiere que el carácter del final de la vista sea NULL. Si pasas un objeto std::wstring_view que no termine en Null, el proceso terminará.

Alternativas para parámetros iterables

winrt::param::iterable<T> y winrt::param::async_iterable<T> simplifican la transferencia de parámetros como IIterable<T>.

Las colecciones de Windows Runtime IVector<T> y IVectorView<T> ya admiten IIterable<T>. Las colecciones de Windows Runtime IMap<K, V> y IMapView<K, V> ya admiten IIterable<IKeyValuePair<K, V>>.

Además de IIterable<T>, también se aceptan las siguientes alternativas. Tenga en cuenta que algunas alternativas solo están disponibles para métodos sincrónicos.

Alternativa Sincronización Async Notas
std::vector<T> const& No
std::vector<T>&& El contenido se mueve a una iteración temporal.
std::initializer_list<T> La versión asincrónica copia los elementos.
std::initializer_list<U> No U debe ser convertible a T.
{ begin, end } No begin y end deben ser iteradores de desvío y *begin debe ser convertible a T.

El iterador doble funciona de manera más general si resulta que tienes una colección que no se ajusta a ninguno de los escenarios anteriores; recuerda que debes poder iterarla y producir elementos que puedan convertirse a T. Por ejemplo, podría tener un IVector<U> o std::vector<U>, donde U se pudiera convertir a T.

En el ejemplo siguiente, el método SetStorageItems espera un IIterable<IStorageItem>. El patrón de iterador doble nos permite pasar otros tipos de colecciones.

// 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

En el caso de IIterable<IKeyValuePair<K, V>>, se aceptan las siguientes alternativas. Tenga en cuenta que algunas alternativas solo están disponibles para métodos sincrónicos.

Alternativa Sincronización Async Notas
std::map<K, V> const& No
std::map<K, V>&& El contenido se mueve a un iterable temporal.
std::unordered_map<K, V> const& No
std::unordered_map<K, V>&& El contenido se mueve a un iterable temporal.
std::initializer_list<std::pair<K, V>> La versión asincrónica copia la lista en una iteración temporal.
{ begin, end } No begin y end deben ser iteradores de desvío, y begin->first y begin->second deben ser convertibles a K y V, respectivamente.

Alternativas para los parámetros de vista vectorial

winrt::param::vector_view<T> y winrt::param::async_vector_view<T> simplifican la transferencia de parámetros a IVectorView<T>.

Se puede llamar a IVector<T>::GetView para obtener un IVectorView<T> desde un IVector<T>.

Además de IVectorView<T>, también se aceptan las siguientes alternativas. Tenga en cuenta que algunas alternativas solo están disponibles para métodos sincrónicos.

Alternativa Sincronización Async Notas
std::vector<T> const& No
std::vector<T>&& El contenido se mueve a una vista temporal.
std::initializer_list<T> La versión asincrónica copia la lista en una vista temporal.
{ begin, end } No begin y end deben ser iteradores de desvío y *begin debe ser convertible a T.

De nuevo, la versión de iterador doble se puede usar para crear vistas vectoriales fuera de las cosas que no se ajusten a una alternativa existente. La vista temporal resulta más eficaz si los iteradores begin y end son iteradores de acceso aleatorio.

Alternativas para los parámetros de vista de mapa

winrt::param::map_view<T> y winrt::param::async_map_view<T> simplifican la transferencia de parámetros como IMapView<T>.

Se puede llamar a IMap<K, V>::GetView para obtener un IMapView<K, V> desde un IMap<K, V>.

Además de IMapView<K, V>, también se aceptan las siguientes alternativas. Tenga en cuenta que algunas alternativas solo están disponibles para métodos sincrónicos.

Alternativa Sincronización Async Notas
std::map<K, V> const& No
std::map<K, V>&& El contenido se mueve a una vista temporal.
std::unordered_map<K, V> const& No
std::unordered_map<K, V>&& El contenido se mueve a una vista temporal.
std::initializer_list<std::pair<K, V>> El contenido se copia en una vista temporal. No se pueden duplicar las claves.

Alternativas para parámetros vectoriales

winrt::param::vector<T> simplifica el paso de parámetros como IVector<T>. Además de IVector<T>, estas alternativas también se aceptan:

Alternativa Notas
std::vector<T>&& El contenido se mueve a un vector temporal. Los resultados no vuelven.
std::initializer_list<T>

Si el método muta el vector temporal, esos cambios no se reflejarán en los parámetros originales. Para observar los cambios, pase un IVector<T>.

Alternativas para los parámetros de mapa

winrt::param::map<K, V> simplifica el paso de parámetros como IMap<K, V>. Además de IMap<K, V>, estas alternativas también se aceptan:

Puede pasar Notas
std::map<K, V>&& El contenido se mueve a un mapa temporal. Los resultados no se mueven de nuevo.
std::unordered_map<K, V>&& El contenido se mueve a un mapa temporal. Los resultados no vuelven.
std::initializer_list<std::pair<K, V>>

Si el método muta el mapa temporal, esos cambios no se reflejarán en los parámetros originales. Para observar los cambios, pase un IMap<K, V>.

Alternativas para los parámetros de matriz

winrt::array_view<T> no está en el espacio de nombres winrt::param, pero se usa para parámetros que sean matrices de estilo C. Además de un array_view<T> explícito, estas alternativas también se aceptan:

Alternativa Notas
{} Matriz vacía.
U[] Matriz de estilo C, donde U se puede convertir a T y sizeof(U) == sizeof(T).
std::array<U, N> Donde U se puede convertir a T y sizeof(U) == sizeof(T).
std::vector<U> Donde U se puede convertir a T y sizeof(U) == sizeof(T).
{ begin, end } begin y end deben ser de tipo T*, que representa el intervalo [begin, end).
std::initializer_list<T>
std::span<U, N> Donde U se puede convertir a T y sizeof(U) == sizeof(T).

Consulta también la entrada de blog Distintos patrones para pasar matrices de estilo C en el límite de ABI Windows Runtime.