您好,登錄后才能下訂單哦!
今天我們來分析QueryInterface函數。
HRESULT CDictionary::QueryInterface(const IID& iid, void **ppv) { if(iid == IID_IUnknown) { *ppv = (IDictionary*)this; ((IDictionary*)(*ppv))->AddRef(); }elseif(iid == IID_Dictionary) { *ppv = (IDictionary*)this; ((IDictionary*)(*ppv))->AddRef(); }elseif(iid == IID_SpellCheck) { *ppv = (ISpellCheck*)this; ((ISpellCheck*)(*ppv))->AddRef(); } else { *ppv = NULL; return E_NOINTERFACE; } return S_OK; }
根據COM接口的內存接口以及C++語言中類多重繼承的內存結構,我們實現QueryInterface函數。
QueryInterface函數對于iid的三種可能值分別進行了處理,不管客戶要想查詢字典對象所支持的哪個接口,QueryInterface都會返回相應的接口指針,如圖,當我們將this指針轉換為基類指針時,所得到的指針正好指向接口的vtable,所以我們用類型轉換函數就可以得到每個接口的vtable,也就是接口指針。
在第一個if語句塊中,我們并沒有把this指針直接轉換為IUnknown指針,根據C++語法,由于在CDictionary的基類樹中,有兩個IUnknown節點,因此直接把this指針轉換成IUnknown指針存在二義性。
先把this指針轉換成IDictionary或者ISpellCheck,再轉換成IUnknown,但必須保證每次查到的IUnknown接口完全一致。
這個程序直接把IDictionary接口指針當做IUnknown接口指針,這樣的轉換是符合COM規范的。
根據CDictionary的基類樹,這里的繼承關系不能用虛擬繼承,否則就不能保證IDictionary和ISpellCheck的vtable與COM接口的vtable的一致性。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。