Pasar parámetros a los límites de la ABI

Con los tipos en el espacio de nombres winrt::param, C++/WinRT simplifica el paso de parámetros a los límites de ABI ya que proporciona conversiones automáticas para casos habituales. Puedes ver más detalles y ejemplos de código en Control de cadenas y Tipos de datos de C++ estándar y C++/WinRT.

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.

Muchos tipos vienen en versiones sincrónicas y asincrónicas. C++/WinRT usa la versión sincrónica cuando está pasando un parámetro a un método asincrónico; para ello, usa la versión asincrónica cuando pasa un parámetro a un método asincrónico. La versión asincrónica realiza pasos adicionales para dificultar que la persona que llama mute la colección antes de que la operación haya finalizado. Sin embargo, ten en cuenta que ninguna de estas variantes te protegen contra la recopilación que se esté mutando desde otro subproceso. Prevenir eso es tu responsabilidad.

Parámetros de cadena

winrt::param::hstring simplifica la operación de pasar parámetros a las API que toman HSTRING.

Tipos que puedes pasar Notas
{} Pasa una cadena vacía.
winrt::hstring
std::wstring_view Para los valores literales, se puede escribir L"Name"sv. La vista debe tener un terminador nulo después del final.
std::wstring -
wchar_t const* Una cadena terminada en null.

nullptr no está permitido. Usa {} en su lugar.

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.

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

Parámetros iterables

winrt::param::iterableT> y > simplifican la transferencia de parámetros a las API que usan <.

Las colecciones de Windows Runtime ya son de tipo Iterable.

Tipos que puedes pasar Sincronización Async Notas
nullptr Debes comprobar que el método subyacente sea compatible con nullptr.
IIterableT> O cualquier elemento que se pueda convertir a él.
std::vector T > const& No
std::vectorT>&& El contenido se mueve al iterador para evitar mutaciones.
std::initializer_listT> La versión asincrónica copia los elementos.
std::initializer_listU> No U debe ser convertible a T.
{ ForwardIt begin, ForwardIt end } No *begin debe ser convertible a *begin.

Tenga en cuenta que IIterable > U y > no están permitidos, incluso si < es convertible a >. Para std::vector > U, puede usar la versión de iterador doble (más detalles a continuación).

En algunos casos, el objeto que tienes puede implementar el valor Iterable que quieras. Por ejemplo, el archivo de almacenamiento IVectorView > generado por > implementa IIterable StorageFile . Pero también implementa IIterable IStorageItem; >solo tiene que solicitarlo explícitamente.

IVectorView<StorageFile> pickedFiles{ co_await filePicker.PickMultipleFilesAsync() };
requestData.SetStorageItems(storageItems.as<IIterable<IStorageItem>>());

En otros casos, puedes usar la versión del iterador doble.

std::vector<StorageFile> storageFiles;
requestData.SetStorageItems({ storageFiles.begin(), storageFiles.end() });

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. Lo usamos anteriormente para iterar un vector de tipos derivados. Aquí lo usaremos para iterar un elemento que no es un vector de tipos derivados.

std::array<StorageFile, 3> storageFiles;
requestData.SetStorageItems(storageFiles); // This doesn't work.
requestData.SetStorageItems({ storageFiles.begin(), storageFiles.end() }); // But this works.

Implementación de IIterator T . GetMany(T[]) es más eficaz si el iterador es RandomAcessIt un . De lo contrario, realizará varias transferencias en el rango.

Tipos que puedes pasar Sincronización Async Notas
nullptr Debes comprobar que el método subyacente sea compatible con nullptr.
IIterableIKeyValuePair<K, V>> O cualquier elemento que se pueda convertir a él.
std::map K, V > const& No
std::mapK, V>&& El contenido se mueve al iterador para evitar mutaciones.
std::unordered_map K, V > const& No
std::unordered_mapK, V>&& El contenido se mueve al iterador para evitar mutaciones.
std::initializer_liststd::pair<K, V>> Los tipos K y V deben coincidir exactamente. No se pueden duplicar las claves. La versión asincrónica copia los elementos.
{ ForwardIt begin, ForwardIt end } No begin->first y begin->second deben ser convertibles a begin->first y begin->secondrespectivamente.

Parámetros de la vista de vector

winrt::param::vector_viewT> y > simplifican la transferencia de parámetros a las API que usan <.

Puedes usar IVectorT.GetView para obtener un elemento IVectorView desde IVector.

Tipos que puedes pasar Sincronización Async Notas
nullptr Debes comprobar que el método subyacente sea compatible con nullptr.
IVectorViewT> O cualquier elemento que se pueda convertir a él.
std::vector T > const& No
std::vectorT>&& El contenido se mueve a la vista para evitar mutaciones.
std::initializer_listT> El tipo debe coincidir exactamente. La versión asincrónica copia los elementos.
{ ForwardIt begin, ForwardIt end } No *begin debe ser convertible a *begin.

La versión de iterador doble se puede usar para crear vistas vectoriales a partir de cosas que no se ajustan a los requisitos necesarios para pasarlas directamente. Ten en cuenta que, como los vectores admiten el acceso aleatorio, es recomendable que pases un RandomAcessIter.

Asignar parámetros de vista

winrt::param::map_viewT> y > simplifican la transferencia de parámetros a las API que usan <.

Puedes usar IMap::GetView para obtener un elemento IMapView de un IMap.

Tipos que puedes pasar Sincronización Async Notas
nullptr Debes comprobar que el método subyacente sea compatible con nullptr.
IMapViewK, V> O cualquier elemento que se pueda convertir a él.
std::map K, V > const& No
std::mapK, V>&& El contenido se mueve a la vista para evitar mutaciones.
std::unordered_map K, V > const& No
std::unordered_mapK, V>&& El contenido se mueve a la vista para evitar mutaciones.
std::initializer_liststd::pair<K, V>> Las versiones sincrónicas y asincrónicas copian los elementos. No se pueden duplicar las claves.

Parámetros de vector

winrt::param::vectorT> simplifica la operación de pasar parámetros a las API que toman >.

Tipos que puedes pasar Notas
nullptr Debes comprobar que el método subyacente sea compatible con nullptr.
IVectorT> O cualquier elemento que se pueda convertir a él.
std::vectorT>&& El contenido se mueve al parámetro para evitar mutaciones. Recuerda que no se devuelven los resultados.
std::initializer_listT> El contenido se copia al parámetro para evitar mutaciones.

Si el método muta el vector, entonces la única forma de observar la mutación es pasar un IVector directamente. Si pasas un std::vector, el método mutará la copia y no el original.

Asignar parámetros

winrt::param::mapT> simplifica la operación de pasar parámetros a las API que toman >.

Tipos que puedes pasar Notas
nullptr Debes comprobar que el método subyacente sea compatible con nullptr.
IMapT> O cualquier elemento que se pueda convertir a él.
std::mapK, V>&& El contenido se mueve al parámetro para evitar mutaciones. Recuerda que no se devuelven los resultados.
std::unordered_mapK, V>&& El contenido se mueve al parámetro para evitar mutaciones. Recuerda que no se devuelven los resultados.
std::initializer_liststd::pair<K, V>> El contenido se copia al parámetro para evitar mutaciones.

Si el método muta la asignación, entonces la única forma de observar la mutación es pasar un IMap directamente. Si pasas un std::map o std::unordered_map, el método mutará la copia y no el original.

Parámetros de matriz

Winrt::array_view T > no está en el espacio de nombres > pero se usa para parámetros que son matrices de estilo C, también conocidascomo matrices compatibles.

Tipos que puedes pasar Notas
{} Una matriz vacía.
array Matriz compatible de C (es decir, ), donde C array[N];C array[N]; se puede convertir a Ty .
std::array C, N> Std::array deC++, donde C se puede convertir a Ty .
std::vector C> Std::vector deC++, donde C se puede convertir a Ty .
{ T*, T* } Un par de punteros que representan el intervalo (comienzo, final).
std::initializer_listT>

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