Share via


QueryInterface:在物件中巡覽

當您有物件上介面的初始指標之後,COM 有一個非常簡單的機制,可找出物件是否支援另一個特定介面,如果是的話,可以取得它的指標。 (如需取得物件上介面的初始指標的相關信息,請參閱取得物件的指標。此機制是 IUnknown 介面的 QueryInterface 方法。 如果物件支援要求的介面,方法必須傳回該介面的指標。 這可讓物件自由巡覽物件所支援的介面。 QueryInterface 會將要求「您支援指定的合約嗎?」與一旦交涉成功之後,該合約的高效能使用區隔。

當用戶端一開始取得物件的存取權時,該用戶端至少會收到IUnknown 介面指標(最基本介面),其可控制物件的存留期,方法是在物件使用 物件完成時告知物件,並叫用 QueryInterface 用戶端會進行程序設計,要求其管理的每個物件執行某些作業,但 IUnknown 介面沒有這些作業的函式。 相反地,這些作業會透過其他介面來表示。 因此,客戶端會設計為與這些介面的對象進行交涉。 具體而言,用戶端會呼叫 QueryInterface 來要求 物件,以取得用戶端可以叫用所需作業的介面。

因為對象會實作 QueryInterface,所以它能夠接受或拒絕要求。 如果物件接受用戶端的要求, QueryInterface 會將要求介面的新指標傳回給用戶端。 透過該介面指標,用戶端可以存取該介面的方法。 另一方面,如果對象拒絕用戶端的要求, QueryInterface 會傳回 Null 指標-錯誤,而用戶端沒有可呼叫所需函式的指標。 在此情況下,客戶端必須正常處理該可能性。 例如,假設客戶端在物件上具有介面 A 的指標,並要求介面 B 和 C。假設物件也支援介面 B,但不支援介面 C。結果是 對象會傳回 B 的指標,並報告不支援 C。

關鍵點是,當物件拒絕對 QueryInterface 的呼叫時,用戶端不可能要求對象執行透過要求介面表示的作業。 客戶端必須有介面指標,才能叫用該介面中的方法。 如果對象拒絕提供要求的指標,則客戶端必須準備好在沒有 的情況下執行,要麼不執行它打算與該對象有關的任何動作,或嘗試回復另一個可能較不強大、更強大的介面。 相較於其他對象導向系統,COM 功能的這項功能與其他對象導向系統相比,您無法知道函式在呼叫該函式之前是否能運作,即便如此,處理失敗也不確定。 QueryInterface 提供可靠且一致的方法來知道物件是否支援介面,然後再嘗試呼叫其方法。

QueryInterface 方法也提供健全且可靠的方法,讓物件指出它不支援指定的合約。 也就是說,如果在對 QueryInterface 的呼叫中,詢問「舊」物件是否支援「新」介面(例如,在舊物件出貨後發明的介面),則舊物件會可靠地執行,而不會造成當機,回答「否」。支援這項技術是配置 IID 的演算法。 雖然這似乎是一個小點,但對於系統的整體架構而言非常重要,而且查詢舊版元素有關新功能的能力出人意料地是,在大部分其他物件架構中不存在的功能。

使用和實作 IUnknown