我在這里找到了這個代碼片段。
wil::com_ptr<IStream> stream;
CHECK_FAILURE(SHCreateStreamOnFileEx(
L"assets/EdgeWebView2-80.jpg", STGM_READ, FILE_ATTRIBUTE_NORMAL,
FALSE, nullptr, &stream));
根據手冊,SHCreateStreamOnFileEx最后一個引數的型別應該是IStream **。但是,代碼片段將 a 傳遞wil::com_ptr<IStream> *給函式而不是 a IStream **。我想知道它是如何作業的。是否wil::com_ptr<IStream>多載運算子&(又名“地址”)?
順便說一句,我找不到wil::com_ptr. 它與winrt::com_ptr 結構模板 (C /WinRT)相同嗎?謝謝。
uj5u.com熱心網友回復:
Windows 實作庫 (WIL)的檔案通過其存盤庫的wiki發布。WinRT 和 COM 包裝器頁面上描述了類wil::com_ptr_t模板1 。
物件管理方法部分列出了三個類成員,它們允許客戶端獲取存盤的介面指標的地址:
T** addressof()
回傳內部指標的地址而不釋放當前的 COM 物件。不要將其用于_Out_引數2,因為它會泄漏當前的 COM 物件。對于_Out_引數,使用&運算子,它在回傳地址之前釋放當前的 COM 物件。T** put()
釋放當前 COM 物件并回傳內部指標的地址。com_ptr_t作為_Out_引數傳遞時使用此方法。T** operator&()
與 相同put()。
所以要回答字面問題:是的,在做一些內務處理后wil::com_ptr_t 是否會多載 operator&()以回傳內部介面指標的地址。
wil::com_ptr_twinrt::com_ptr與類模板3無關,它是C /WinRT庫的一部分。它們都與 ATLCComPtr或 Visual Studio 的_com_ptr_t. 以上是四種官方實作,雖然它們都具有自動化 COM 物件生命周期管理的相同目標,但它們的實作方式略有不同,產生了令人驚訝的后果4。
差異體現在以下幾個方面:
帶有介面指標引數的建構式
實作可以選擇是承擔傳入介面指標的所有權,還是模型共享所有權,讓呼叫者負責處理
Release()傳入的介面指標。接受介面指標的賦值運算子
與上面關于傳入指標的相同,增加了必須處理實體已經持有介面指標的情況。實作可以:
- 靜默洗掉當前持有的介面指標(這是一個錯誤并不意味著你不會看到它)
Release()在分配傳入介面指標之前靜默當前介面- 如果實體持有介面指標,則拋出例外
檢索原始介面指標的地址
與上面的賦值類似,智能指標實體已經持有一個介面的情況需要以一種或另一種方式處理:
- 靜默洗掉存盤的介面(例如
addressof()) - 靜默
Release()當前界面(例如put()) - 如果存盤的指標不是
nullptr
- 靜默洗掉存盤的介面(例如
如果您決定使用 COM 智能指標實作,請確保您牢牢掌握它的語意。根據所使用的庫,同一段 C 代碼的行為可能會有所不同。
1 wil::com_ptr是模板引數設定為的別名模板。wil::com_ptr_terr_policyerr_exception_policy
2 即使標記為引數,問題中的代碼段也可以安全通過。我猜作者是為了一致性、可讀性和可維護性而使用的。stream.addressof()ppstm_Out_operator&()
3 雖然 WIL 和 C /WinRT 是獨立的庫,但它們可以毫不費力地進行互操作。
4 我們正在使用智能指標,所以我們不可能成為泄漏的源頭
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/428313.html
