對象間通訊
COM 的設計目的是允許用戶端以透明方式與物件通訊,不論這些物件在相同進程中、在同一部計算機上或不同計算機上執行的位置。 這可為所有類型的物件,以及物件用戶端和物件伺服器提供單一程序設計模型。
從客戶端的觀點來看,所有對象都會透過介面指標來存取。 指標必須是進程中的。 事實上,對接口函式的任何呼叫一律會先到達一些進程內程序代碼。 如果對像是同進程,則呼叫會直接到達它,而不需要介入系統基礎結構程序代碼。 如果對像是跨進程,呼叫會先到達 COM 或物件所提供的所謂的「Proxy」物件(如果實作者想要的話)。 Proxy 封裝會呼叫參數(包括任何介面指標),並針對對象實作所在的其他進程或其他計算機產生適當的遠端過程調用(或自定義產生的 Proxy 時的其他通訊機制)。 此封裝指標以跨進程界限傳輸的程序稱為 封送處理。
從伺服器的觀點來看,物件介面函式的所有呼叫都是透過該介面的指標進行。 同樣地,指標只會在單一進程中具有內容,而且呼叫端一律必須是一些進程內程序代碼。 如果物件正在處理中,呼叫端就是用戶端本身。 否則,呼叫端是 COM 或物件本身提供的「存根」物件。 存根會從客戶端進程中的 「proxy」 接收遠端過程調用(或其他通訊機制),並取消分割參數,並在伺服器物件上呼叫適當的介面。 從客戶端和伺服器的觀點來看,它們一律會直接與一些其他同進程程式代碼通訊。
COM 提供封送處理實作,稱為 標準封送處理。 此實作非常適用於大部分物件,並大幅降低程序設計需求,讓封送處理程式有效透明。
不過,介面與 COM 程式透明度實作的明確區隔,在某些情況下可能會有所阻礙。 以客戶端觀點為主的介面設計,有時可能會導致設計決策與跨網路有效實作該介面的有效率實作衝突。 在這種情況下,需要的不是純粹的程式透明度,而是「程序透明度,除非您需要注意」。COM 藉由允許物件實作器支援自定義封送處理(也稱為IMarshal 封送處理)來提供這項功能。 標準封送處理實際上是自定義封送處理實例;這是物件不需要自定義封送處理時使用的預設實作。
您可以實作自定義封送處理,以允許對象在透過網路使用時採取不同的動作,而不是在本機存取下執行,而且對用戶端而言完全透明。 此架構可讓您設計用戶端/物件介面,而不考慮網路效能問題,稍後再解決網路效能問題,而不會中斷已建立的設計。
COM 不會指定元件的結構方式;它會指定其互動方式。 COM 會將元件的內部結構留給程式設計語言和開發環境。 相反地,程式設計環境沒有設定使用立即應用程式外部對象的標準。 例如,Microsoft Visual C++ 適用於在應用程式內操作物件,但不支援在應用程式外部使用物件。 一般而言,所有其他程式設計語言在這方面都相同。 因此,若要透過與語言無關的介面提供全網路互操作性,COM 會挑選程式設計語言離開的位置。
vtbl 結構的雙重間接表示函式指標數據表中的指標不需要直接指向 real 物件中的實際實作。 這是流程透明度的核心。
對於進程內伺服器,其中物件會直接載入客戶端進程,數據表中的函式指標會直接指向實際實作。 在此情況下,從用戶端到介面方法的函式呼叫會直接將執行控件傳送至 方法。 不過,這不適用於本機,更別說是遠端對象,因為進程之間無法共用記憶體指標。 不過,客戶端必須能夠呼叫介面方法,就像呼叫實際實作一樣。 因此,客戶端會藉由呼叫,將控制權統一傳輸至某個物件中的方法。
用戶端一律會呼叫某些進程內物件的介面方法。 如果實際對像是本機或遠端,則會呼叫 Proxy 物件,然後對實際物件進行遠端過程調用。
那麼,實際執行的方法為何? 答案是,每當呼叫跨進程介面時,每個介面方法都會由 Proxy 對象實作。 Proxy 物件一律是代表所呼叫對象的進程內物件。 這個 Proxy 物件知道實際物件是在本機或遠端伺服器中執行。
Proxy 物件會封裝某些數據封包中的函式參數,併產生本機或遠端物件的 RPC 呼叫。 該封包是由本機或遠端計算機上伺服器進程中的存根物件所挑選,該物件會解壓縮參數,並呼叫 方法的實際實作。 當該函式傳回時,存根會封裝任何 out 參數和傳回值,並將它傳回 Proxy,以將其解壓縮並傳回原始用戶端。
因此,客戶端和伺服器一律會彼此通訊,就好像一切都在處理中一樣。 來自用戶端的所有呼叫,以及伺服器的所有呼叫,都會在某個時間點進行進程。 但是,因為 vtbl 結構允許 COM 等某些代理程式攔截所有函式呼叫,而且所有從函式傳回,代理程式可以視需要將這些呼叫重新導向至 RPC 呼叫。 雖然同進程內呼叫的速度比跨進程呼叫更快,但對客戶端和伺服器而言,進程差異完全透明。
如需詳細資訊,請參閱下列主題:
相關主題