微軟COM元件的理解(引用)
連結:https://www.zhihu.com/question/49433640/answer/115952604
來源:知乎
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。 這篇知乎答案算是解釋com元件技術比較通俗的,在此引用記錄一下。
解釋不解釋也都是死掉了的技術了啊……
COM主要是一套給C/C++用的介面,當然為了微軟的野心,它也被推廣到了VB、Delphi以及其他一大堆奇奇怪怪的平臺上。它主要為了使用dll釋出基於interface的介面。我們知道dll的介面是為了C設計的,它匯出的基本都是C的函式,從原理上來說,將dll載入到記憶體之後,會告訴你一組函式的地址,你自己call進去就可以呼叫相應的函式。
但是對於C++來說這個事情就頭疼了,現在假設你有一個類,我們知道使用一個類的第一步是建立這個類:new MyClass()。這裡直接就出問題了,new方法通過編譯器計算MyClass的大小來分配相應的記憶體空間,但是如果庫升級了,相應的類可能會增加新的成員,大小就變了,那麼使用舊的定義分配出來的空間就不能在新的庫當中使用。
要解決這問題,我們必須在dll當中匯出一個CreateObject的方法,用來代替建構函式,然後返回一個介面。然而,介面的定義在不同版本當中也是有可能會變化的,為了相容以前的版本同時也提供新功能,還需要讓這個物件可以返回不同版本的介面。介面其實是一個只有純虛擬函式的C++類,不過對它進行了一些改造來相容C和其他一些程式語言。
在這樣改造之後,出問題的還有析構過程~MyClass()或者說delete myClass,因為同一個物件可能返回了很多個介面,有些介面還在被使用,如果其中一個被人delete了,其他介面都會出錯,所以又引入了引用計數,來讓許多人可以共享同一個物件。
其實到此為止也並不算是很奇怪的技術,我們用C++有的時候也會使用Factory方法來代替建構函式實現某些特殊的多型,也會用引用計數等等。COM技術的奇怪地方在於微軟實在是腦洞太大了,它們構造了一個作業系統級別的Factory,規定所有人的Interface都統一用UUID來標識,以後想要哪個Interface只要報出UUID來就行了。這樣甚至連連結到特定的dll都省了。
這就好比一個COM程式設計師,只要他在Windows平臺上,呼叫別的庫就只要首先翻一下魔導書,查到了一個用奇怪文字寫的“Excel = {xxx-xxx-xxxx...}”的記號,然後它只要對著空中喊一聲:“召喚,Excel!CoCreateInstance, {xxx-xxx-xxxx...}”
然後呼的從魔法陣裡面竄出來了一個怪物,它長什麼樣我們完全看不清,因為這時候它的型別是IUnknow,這是腦洞奇大無比的微軟為所有介面設計的一個基類。我們需要進一步要求它變成我們能控制的介面形態,於是我們再喊下一條指令:
“變身,Excel 2003形態!QueryInterface, {xxx-xxx-xxxx...}”
QueryInterface使用的是另一個UUID,用來表示不同版本的介面。於是怪物就變成了我們需要的Excel 2003介面,雖然我們不知道它實際上是2003還是2007還是更高版本。
等我們使喚完這隻召喚獸,我們就會對它說“回去吧,召喚獸!Release!”但是它不一定聽話,因為之前給它的命令也許還沒有執行完,它會忠誠地等到執行完再回去,當然我們並不關心這些細節。
微軟大概會覺得自己設計出了軟體史上最完美的二進位制介面,從今以後所有的第三方庫都可以涵蓋在這套介面之下。然而歷史的車輪是無情的,它碾過那些自以為是的人的速度總是會比想象的更快。Java的直接基於類的介面被廣泛應用,開發使用起來遠遠來的簡單,即便偶爾出點問題大家也都想辦法解決了,事實證明程式設計師並不願意花10倍的編寫程式碼的時間來解決二進位制庫的版本相容問題,他們更願意假裝沒看見。很快微軟也抄了一個.NET託管dll的方案出來,於是純的二進位制介面COM就慢慢被拋棄了。
COM,OLE,ActiveX,OCX,VBScript,歷史不會忘記你們的,如果歷史忘了,我替歷史記住你們。安息吧。
=============================================================
這怎麼還火了,這不應該是一個討論遺留技術的冷門問題嗎……
補充說明一下,其實並沒有貶低COM的意思,COM在當時一定是一個偉大的發明,只是技術革新太快。到今天,其實COM都是C++的二進位制本機程式碼的動態連結的最佳的選擇(Windows上的)。但是,C++,二進位制本機程式碼,動態連結,這三件事現在沒有一件是重要的……COM在Windows作業系統底層繼續發揮餘熱的時間肯定還會很長,因為永遠都會有偏底層的C++開發的需要,必須遊戲之類。只是技術趨勢已經很明確了。