將參數傳遞至投影 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"svL"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> 已可支援 IIterableI<KeyValuePair<K, V>>

除了 IIterable<T> 之外,也接受下列替代項目。 請注意,某些替代項目僅適用於同步方法。

替代函式 同步 Async 備註
std::vector<T> const& No
std::vector<T>&& Yes Yes 內容會移至暫時的可迭代物件中。
std::initializer_list<T> Yes Yes 非同步版本會複製這些項目。
std::initializer_list<U> No U 必須可轉換成 T
{ begin, end } No beginend 必須是正向迭代器,而且 *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& No
std::map<K, V>&& Yes Yes 內容會移至暫時的可迭代物件中。
std::unordered_map<K, V> const& No
std::unordered_map<K, V>&& Yes Yes 內容會移至暫時的可迭代物件中。
std::initializer_list<std::pair<K, V>> Yes Yes 非同步版本會將清單複製到暫時的可迭代物件中。
{ begin, end } No beginend 必須是正向迭代器,而且 begin->firstbegin->second 必須分別可轉換成 KV

向量檢視參數的替代項目

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& No
std::vector<T>&& Yes Yes 內容會移至暫時的檢視中。
std::initializer_list<T> Yes Yes 非同步版本會將清單複製到暫時的檢視中。
{ begin, end } No beginend 必須是正向迭代器,而且 *begin 必須可轉換成 T

同樣地,雙重迭代器版本可以用來建立不符合現有替代項目的向量檢視。 如果 beginend 迭代器是隨機存取迭代器,暫時檢視會更有效率。

地圖檢視參數的替代項目

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& No
std::map<K, V>&& Yes Yes 內容會移至暫時的檢視中。
std::unordered_map<K, V> const& No
std::unordered_map<K, V>&& Yes Yes 內容會移至暫時的檢視中。
std::initializer_list<std::pair<K, V>> Yes Yes 內容會複製到暫時檢視中。 索引鍵不得重複。

向量參數的替代項目

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 可轉換成 Tsizeof(U) == sizeof(T)
std::array<U, N> 其中 U 可轉換成 Tsizeof(U) == sizeof(T)
std::vector<U> 其中 U 可轉換成 Tsizeof(U) == sizeof(T)
{ begin, end } beginend 的類型必須是 T*,代表範圍 [begin, end)。
std::initializer_list<T>
std::span<U, N> 其中 U 可轉換成 Tsizeof(U) == sizeof(T)

另請參閱部落格文章:將 C 樣式陣列傳遞到 Windows 執行階段 ABI 界限的各種模式