1. 程式人生 > >C++ COM程式設計之QueryInterface函式(二)

C++ COM程式設計之QueryInterface函式(二)

前言

COM程式設計——認識元件中也總結了,COM是一個說明如何建立可動態互變元件的規範,它提供了為保證能夠互操作,客戶和元件應遵循的一些標準。而在實現和使用QueryInterface時,就需要去遵守一些規則,只有遵守了這些規則,才能是一個正確的COM元件;只有瞭解了這些規則,才能會真正的瞭解COM開發。

QueryInterface的實現規則

實現QueryInterface需要遵從以下五條規則:

1.QueryInterface總是返回同一IUnknown指標

元件的例項只有一個IUnknown介面。因為當查詢元件例項的IUnknown介面時,不論通過哪個介面,所得到的均將是同一指標值。為確定兩個介面是否指向同一個元件,可以通過這兩個介面查詢IUnknown介面,然後將返回值進行比較。

這條規則是非常重要的,如果QueryInterface的實現不遵循這條規則的話,則將沒法決定兩個介面是否指向同一組件;

2.如果客戶曾經獲取過某個介面,那麼它將總能獲得該介面

這條規則限定了對於一個元件例項,它的QueryInterface的不變性;你可以想象,如果元件例項的介面集不是固定的,客戶將無法通過程式設計的方法來決定一個元件到底具有一些什麼樣的功能;客戶就會對你的COM元件失去耐心,你的COM元件都沒有人去使用了,這還有什麼意義。

3.客戶可以再次獲取已經擁有的介面

如果客戶擁有一個IX介面,則可以通過它來再次查詢IX介面指標,並且一定可以成功的。通過自己查詢自己,聽起來多少有點奇怪,但是這是必須可以的。

4.客戶可以從任何介面返回到起始介面

如果客戶擁有一個IX介面指標,併成功地使用它來查詢了一個IY介面,那麼它將可以使用這個IY介面來查詢一個IX介面,這條規則在實際的專案開發時很有用。

5.如果能夠從某介面獲取某特定介面,則從任意介面都將能獲取此介面

如果能夠從某個元件獲取某特定介面,那麼客戶將可以通過此元件所支援的任意介面獲取此介面。例如:如果可以通過介面IX得到介面IY,通過IY可以得到IZ,那麼通過IX也將可以得到IZ。這條規則使得QueryInterface是可用的。

綜上所有規則,其內在的重點在於不管元件實現了多少個介面,元件都只實現了一個QueryInterface,所以,在所有的介面的vtbl中,對應的QueryInterface都是元件實現的QueryInterface的地址,所有介面指標呼叫QueryInterface進行查詢時,都是呼叫的同一個QueryInterface,所以,這就滿足了上述的規則。大家在閱讀上面的這些規則時,難免會有些無所謂的感覺,覺得都是文字,很枯燥,我開始的時候也是這樣的;就是因為如此,在實際的開發中,吃過不少的苦頭,所以,今天又在這裡把這些規則重新的整理一遍,希望大家不要在實際的專案中栽了跟頭再回來尋找原因,何不防範於未然呢?

新增新的介面

以前的博文也總結過了,COM中介面是不會發生變化的。當元件釋出一個介面並被某個客戶使用之後,此介面將決不會發生任何變化,而將永遠保持不變。這裡說的不變,具體是什麼意思呢?由於每一個介面都有一個唯一對應的介面識別符號IID。一般情況下,我們不會改變介面,而可以建立一個新介面併為之指定一個新的IID。當QueryInterface接收到對老的IID的查詢時,它將返回老的介面;而當它收到對新的IID的查詢時,它將返回新的介面。對於QueryInterface而言,一個IID就是一個介面。

所以同某個IID相應的介面將絕不會發生變化。新介面可以繼承老的介面,它也可以同老介面完全不同。由於老的介面仍然保持不變,已有客戶的執行將不會受到任何影響。而新客戶則可以自行決定是使用老介面還是新介面,因它可以自由決定到底是查詢哪個介面。

新介面命名

雖然每個人的命名規則,每個公司命名規則都是要求不同的,但是對於COM介面的命名大體上都是一致的,例如:原來的介面名為IX,則新的介面名為IX2,而不是IXEx之類的。我經歷了這麼多的專案,寫過、也呼叫過很多的COM元件,基本都是遵循的這個規則,即在老名稱的後面加上一個數字。

總結

這篇文章總結的是理論,讓那些不喜歡理論的人會有點失望。但是,道理就是那樣的,沒有理論作為基礎的實踐,都是亂搞。做什麼事情,都要有一定的理論基礎,所以,我通過了兩篇博文,對QueryInterface進行詳細的總結。希望對大家有一定的幫助,最後,也希望大家提出你的想法和我分享。我堅信,交流是一種非常給力的學習方法。