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& | Sí | No | |
std::vector<T>&& | Sí | Sí | El contenido se mueve a una iteración temporal. |
std::initializer_list<T> | Sí | Sí | La versión asincrónica copia los elementos. |
std::initializer_list<U> | Sí | No | U debe ser convertible a T. |
{ begin, end } |
Sí | 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& | Sí | No | |
std::map<K, V>&& | Sí | Sí | El contenido se mueve a una iteración temporal. |
std::unordered_map<K, V> const& | Sí | No | |
std::unordered_map<K, V>&& | Sí | Sí | El contenido se mueve a una iteración temporal. |
std::initializer_list<std::pair<K, V>> | Sí | Sí | La versión asincrónica copia la lista en una iteración temporal. |
{ begin, end } |
Sí | 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& | Sí | No | |
std::vector<T>&& | Sí | Sí | El contenido se mueve a una vista temporal. |
std::initializer_list<T> | Sí | Sí | La versión asincrónica copia la lista en una vista temporal. |
{ begin, end } |
Sí | 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& | Sí | No | |
std::map<K, V>&& | Sí | Sí | El contenido se mueve a una vista temporal. |
std::unordered_map<K, V> const& | Sí | No | |
std::unordered_map<K, V>&& | Sí | Sí | El contenido se mueve a una vista temporal. |
std::initializer_list<std::pair<K, V>> | Sí | Sí | 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.