目前windows上有三套模塊交互的標準。第一套,dll,第二套COM,第三套.NET。衆所周知,win32是通過dll的導出表這種方式暴露的一整套非oop的函數,這是第一套的典型代表。第二套的代表
是DirectX等等。
要體會COM的目的,就必須從dll的不方便之處說起。第一,dll暴露的是純函數,沒有面向對象,當然,用c++做dll,類也是可以導出的,但這又牽涉到第二點。這個第二點就是,你如果導出一個指
針類型,vb等這些沒有指針的語言該怎麼處理呢?所以就需要一套獨立於所有語言的,數據交互格式。第三,導出的函數是線程安全嗎?也就是兩個線程可以同時訪問嗎?是可以再進入的嗎?
(reenterable)等等。這些問題dll的簡單的導出表是無法回答的,只能自己在兩個模塊的編程人員上協商好。既然如此,在模塊需要大量交互的情況下,編程人員還要做很多附加的工作,微軟索性就重新
修訂了一套模塊交互標準,把如上的這些因素都考慮進去,這就是COM的初衷。
在COM裏,一個接口可以看成一個dll的導出表,一個COM對象不再像dll那樣,只能有一張導出表了,COM對象可以有N個接口,每個接口可以導出一大溜函數。當然,COM必須規定這些接口的標
準,而且是在二進制上(彙編級的),也就是在內存上的每個接口是什麼樣子的(大概就是c++的虛函數表的樣子),因爲COM要跨語言。兩個語言如果對接口的內存模型不一致,一個call過去,結果
call錯了東西,不是函數,程序就崩潰了。同時,COM還要規定接口裏可用的各種數據格式。最後,COM提出了一個套間(apartment)的概念,套間說白了就是一種協調緩衝機制,在這種機制下,不
管對方是單線程訪問你,還是多線程,COM通過處理,最終都能轉成不會讓你崩潰的方式來訪問你的代碼,你的代碼就達到了線程透明。
線程透明,大概的過程如此,當多個線程同時訪問你代碼的時候,COM的套間的實現代碼就像小蜜一樣,會叫他們一個個排隊,這樣,最終到你代碼裏的,其實已經是單線程的調用了,所以,你的
代碼不會崩潰。COM的這種“小蜜”技術,既然可以實現線程透明,顯然還可以推廣,於是進程透明,網絡透明都可以做到了,中間步驟交給“小蜜”處理就好了。
在第二套模塊交互標準建立之後,微軟大部分的API就不單用dll函數的方式暴露了,更多是用COM來暴露,比如DirectX,瀏覽器的二次開發等等。
由上可知,如果你的程序交互簡單,大可不必用COM,用個dll導出表,足矣。如果程序導出的功能較多叫複雜,還是用COM這種方式暴露出接口爲好,這樣比較清晰。很多人說COM死了。我覺得
看你怎麼看,如果說COM功能會被移除,這幾乎是不可能的,因爲只是一套標準而已,而且還有諸多基於COM的程序。但微軟基本上不會用COM的這套標準來暴露API了,這可能是事實。