将参数传递给投影 API
对于某些类型,C++/WinRT 提供了将参数传递到投影 API 的替代方法。 这些接受参数的类放置在 winrt::param 命名空间中。 仅 C++/WinRT 生成的代码应使用这些类;请勿在自己的函数和方法中使用它们。
重要
不应自行使用 winrt::param 命名空间中的类型。 它们的用途是为投影提供帮助。
其中一些替代项区分同步调用和异步调用。 异步调用的版本通常获取参数数据的所有权,以确保值在异步调用完成之前保持有效且保持不变。 但注意,此保护不会扩展到从另一个线程对集合的更改。 防止从另一个线程中转变集合是你的责任。
字符串参数的替代项
winrt::param::hstring 简化了将参数作为 winrt::hstring 传递的过程。 除了 winrt::hstring,还接受以下替代项:
替代项 | 说明 |
---|---|
{} |
空字符串。 |
std::wstring_view | 视图必须后跟 null 终止符。 |
std::wstring | |
wchar_t const* | 以 null 终止的字符串。 |
无法传递 nullptr
来表示空字符串。 请改为使用 L""
或 {}
。
编译器知道在编译时如何评估字符串文本上的 wcslen
。 因此,对于文本,L"Name"sv
和 L"Name"
是等效的。
请注意,std::wstring_view 对象不以 null 终止,但 C++/WinRT 要求视图末尾后的字符为 null。 如果你传递并非以 null 终止的 std::wstring_view,则过程将会终止。
可迭代参数的替代方法
winrt::param::iterable<T> 和 winrt::param::async_iterable<T> 简化了将参数作为 IIterable<T> 传递的过程。
Windows 运行时集合 IVector<T> 和 IVectorView<T> 已支持 IIterable<T>。 Windows 运行时集合 IMap<K, V> 和 IMapView<K, V> 已支持 IIterable<IKeyValuePair<K, V>>。
除了 IIterable<T>,还接受以下替代项。 请注意,某些替代项仅适用于同步方法。
替代项 | 同步 | Async | 备注 |
---|---|---|---|
std::vector<T> const& | 是 | 否 | |
std::vector<T>&& | 是 | 是 | 内容将移动到临时可迭代对象中。 |
std::initializer_list<T> | 是 | 是 | 异步版本复制这些项。 |
std::initializer_list<U> | 是 | 否 | U必须可转换为 T。 |
{ begin, end } |
是 | 否 | begin 和 end 必须为前向迭代器,且 *begin 必须可转换为 T。 |
双迭代器更普遍适用于你有一个不适合以上任何方案的集合的情况,只要你可以循环访问它并生成可以转换为 T 的内容。例如,你可能具有 IVector<U> 或 std::vector<U>,其中 U 可转换为 T。
在以下示例中,SetStorageItems 方法需要 IIterable<IStorageItem>。 使用双迭代器模式,可以传递其他类型的集合。
// 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
对于 IIterable<IKeyValuePair<K, V>>,接受以下替代项。 请注意,某些替代项仅适用于同步方法。
替代项 | 同步 | Async | 备注 |
---|---|---|---|
std::map<K, V> const& | 是 | 否 | |
std::map<K, V>&& | 是 | 是 | 内容将移动到临时可迭代对象中。 |
std::unordered_map<K, V> const& | 是 | 否 | |
std::unordered_map<K, V>&& | 是 | 是 | 内容将移动到临时可迭代对象中。 |
std::initializer_list<std::pair<K, V>> | 是 | 是 | 异步版本将列表复制到临时可迭代对象中。 |
{ begin, end } |
是 | 否 | begin 和 end 必须为前向迭代器,且 begin->first 和 begin->second 必须分别可转换为 K 和 V。 |
矢量视图参数的替代项
winrt::param::vector_view<T> 和 winrt::param::async_vector_view<T> 简化了将参数作为 IVectorView<T> 传递的过程。
可以调用 IVector<T>::GetView 从 IVector<T> 获取 IVectorView<T>。
除了 IVectorView<T>,还接受以下替代项。 请注意,某些替代项仅适用于同步方法。
替代项 | 同步 | Async | 备注 |
---|---|---|---|
std::vector<T> const& | 是 | 否 | |
std::vector<T>&& | 是 | 是 | 内容将移动到临时视图中。 |
std::initializer_list<T> | 是 | 是 | 异步版本将列表复制到临时视图中。 |
{ begin, end } |
是 | 否 | begin 和 end 必须为前向迭代器,且 *begin 必须可转换为 T。 |
同样,双迭代器版本可用于从那些不适合现有替代项的内容创建矢量视图。
如果 begin
和 end
迭代器是随机访问迭代器,则临时视图更高效。
映射视图参数的替代项
winrt::param::map_view<T> 和 winrt::param::async_map_view<T> 简化了将参数作为 IMapView<T> 传递的过程。
可以调用 IMap<K, V>::GetView,从 IMap<K, V> 获取 IMapView<K, V>。
除了 IMapView<K, V>,还接受以下替代项。 请注意,某些替代项仅适用于同步方法。
替代项 | 同步 | Async | 备注 |
---|---|---|---|
std::map<K, V> const& | 是 | 否 | |
std::map<K, V>&& | 是 | 是 | 内容将移动到临时视图中。 |
std::unordered_map<K, V> const& | 是 | 否 | |
std::unordered_map<K, V>&& | 是 | 是 | 内容将移动到临时视图中。 |
std::initializer_list<std::pair<K, V>> | 是 | 是 | 内容将复制到临时视图中。 键不能重复。 |
矢量参数的替代项
winrt::param::vector<T> 简化了将参数作为 IVector<T> 传递的过程。 除了 IVector<T>,还接受以下替代项:
替代项 | 备注 |
---|---|
std::vector<T>&& | 内容将移动到临时矢量中。 结果不会移回。 |
std::initializer_list<T> |
如果该方法改变了临时矢量,则这些更改不会反映在原始参数中。 若要观察更改,请传递 IVector<T>。
映射参数的替代项
winrt::param::map<K, V> 简化了将参数作为 IMap<K, V> 传递的过程。 除了 IMap<K, V>,还接受以下替代项:
可以传递 | 备注 |
---|---|
std::map<K, V>&& | 内容将移动到临时映射中。 结果不会移回。 |
std::unordered_map<K, V>&& | 内容将移动到临时映射中。 结果不会移回。 |
std::initializer_list<std::pair<K, V>> |
如果该方法改变了临时映射,则这些更改不会反映在原始参数中。 若要观察更改,请传递 IMap<K, V>。
数组参数的替代项
winrt::array_view<T> 不在 winrt::param 命名空间中,但对于作为 C 样式数组的参数,可以使用它。 除了显式 array_view<T>,还接受以下替代项:
替代项 | 说明 |
---|---|
{} |
空数组。 |
U[] | C 样式数组,其中 U 可转换为 T,且 sizeof(U) == sizeof(T) 。 |
std::array<U, N> | 其中 U 可转换为 T,且 sizeof(U) == sizeof(T) 。 |
std::vector<U> | 其中 U 可转换为 T,且 sizeof(U) == sizeof(T) 。 |
{ begin, end } |
begin 和 end 的类型必须为 T*,表示范围 [begin , end ]。 |
std::initializer_list<T> | |
std::span<U, N> | 其中 U 可转换为 T,且 sizeof(U) == sizeof(T) 。 |
另请参阅博客文章跨 Windows 运行时 ABI 边界传递 C 样式数组的多种模式。