蠍子
當你處理應用程式相容性方面的問題時候,你會發現一個規律:一些能奏效的解決方案,雖然它可以正常工作,但是也只是恰好能正常工作。今天我們來看看非常著名的COM介面IUnknown的QueryInterface方法被誤用的例子。
猿友們可能會問了:這個介面是COM的根介面,為什麼還會被人誤用呢?那就讓我給你們來”翻譯翻譯”。
忘記響應IUnknown介面有時候,COM的開發者會非常興奮地在程式碼實現中對QueryInterface請求做著各種響應,但是,唯獨他忘記響應IUnknown這個介面了,下面就是一個例子:
以上程式碼將會返回錯誤程式碼:E_NOINTERFACE。
忘記響應物件自身介面有一些COM物件的方法會返回一個另外一個COM物件,如果你使用這個返回的物件,並查詢物件自身的介面,它會疑惑的問你:”啊!嘛呢?”我們來看下面的例子:
有一些物件的實現中,對查詢它自身介面的請求,也只是簡單的返回E_NOINTERFACE錯誤,就好像在對COM物件的使用者說:”嘿,哥們,我不存在哦!”。
忘記響應基類介面當你嘗試實現一個繼承介面,這就會加上一條隱含條件,也即:你除了需要實現繼承物件的介面,還需要實現基類介面。有些開發者會忘記對基類的QueryInterface的查詢請求,而是簡單地返回E_NOINTERFACE,下面是一個例子:
忘記實現介面查詢的等效原則原則上來說,下面的程式碼應該是等效的:
在真實的開發者世界裡,有一些COM開發者會編寫錯誤的COM實現程式碼,而導致上面例子中的第二個CoCreateInstance呼叫失敗。唯一可以成功地建立物件的方式是使用IShellFolder接口裡建立它。
忘記設定返回指標為空當客戶傳入一個指標的時候,如果我們不支援這一請求,則按照慣例,我們需要經此指標設定為空指標,但是有些COM開發者常常會忘記這樣做,我們來看下面的程式碼:
如果QueryInterface能成功查詢都目標介面,則pmbl指標必須被設定為非空,如果失敗了,則pmbl必須設定為空,否則,就是不講武德。
桌面外殼必須有能力支援各種各樣充滿問題的COM物件,如果這一相容性被破壞掉了,則客戶就會開始不高興了。一些比較流行的應用程式如果因為以上的原因出問題了,那人們就會說:驚!千萬別升級到Windows XXX版本,因為它不相容XXX。
有人還會說了:”瞧瞧,Microsoft故意讓它的新版本不相容XXX,是不是又想壟斷啊?”
總結所以,規範的執行還是很重要的。
最後Raymond Chen的《The Old New Thing》是我非常喜歡的部落格之一,裡面有很多關於Windows的小知識,對於廣大Windows平臺開發者來說,確實十分有幫助。本文來自:《The ways people mess up IUnknown::QueryInterface》