什麼是代理和存根

來源:互聯網
上載者:User


URL: http://zxjgoodboy.blog.sohu.com/74249273.html

什麼是代理和存根 

      

       打個比方,你到自動取款機上去取款;你就是客戶,取款機就是你的代理;你不會在乎

錢具體放在那裡,你只想看到足夠或更多的錢從出口出來(這就是com的透明性)。你同銀行之間的操作完全是取款機代理實現。  你的取款請求通過取款機,傳到另一頭,銀行的伺服器,他也沒有必要知道你在哪兒取錢,他所關心的是你的身份,和你取款多少。當他確認你的許可權,就進行相應的操作,返回操作結果給取款機,取款機根據伺服器返回結果,從保險柜裡取出相應數量的錢給你。你取出卡後,操作完成。  取款機不是直接同伺服器串連的,他們之間還有一個“存根”,取款機與存根通訊,伺服器與存根通訊。從某種意義上說存根就是伺服器的代理。

ASPectratio="t" v:ext="edit">

圖1 組件間通訊

       如兩個組件之間不是直接通訊,而是通過代理和存根來之間的通訊來間接實現的。圖中的channel是com庫的一部分。

       COM裡,只有進程外組件才會用到代理(proxy)和存根(stub)。

       代理在客戶的進程內建立,存根在組件com對象的進程中建立。 每個介面的每個函數都有自己的代理和存根。

 

為什麼要用代理和存根 

      

       客戶為什麼要用代理和存根,而不直接同對象串連呢? 給你一個理由,對客戶來說,他與所有com對象的串連都是通過指標來調用的, 而對服務來說,調用對象的介面函數也是通過指標來完成的,然而,指標只有在同一進程內才會有效。這樣,代理和存根為了完成這個使命也就產生了。

       代理和存根的作用不只這些,他還要打包所有的參數(包括介面指標),產生 RPC(遠程進程調用),通向另一個進程,或者對象運行所在的另一台機器。

 

圖2  代理的結構

       所顯示的代理結構支援參數的標準列集。每個介面的代理實現了IRpcProxyBuffer介面,用於內聚各個部分之間的相互連信。當代理準備把已列集的參數傳遞過進程邊界時,他調用IRpcChannelBuffer 介面的方法(該介面由channel實現)。channel調用RPC運行庫使資料轉送到目的地。

圖3 存根的結構

       如所示,每個介面的存根被串連到對象的相應介面上。chnnel分發傳入的訊息到適當的介面的存根。所有的組件通過IRpcChannelBuffer介面與chnnel交流,這個介面提供了與RPC運行庫的串連。

 

列集(marshalling

       說到代理和存根,自然少不了列集,什麼是列集?

       列集,對函數參數進行打包處理得過程,因為指標等資料,必須通過一定得轉換,才能被另一組件所理解,列集完成後,RPC調用就會產生。可以說列集是一種資料格式的轉換方法。

列集有3種方式:

1. 類型庫列集

       它可以列集與OLEAUTOMATION相容的任何介面,意思是你的介面的傳回值必須是HRESULT,所使用的參數的類型也應該是與C++的VARIANT結構相容。

2. 通過建立Stub / proxy DLL

       這個DLL的源代由MIDL產生。你必須在伺服器和客戶機上都註冊這個DLL(這是標準的marshal 方式)使用吃方法時,最好把stub / proxy代碼編譯作為一個獨立的組件。

3. 自訂marshaling

       自訂marshal要求在你的組件中必須實現IMarshal介面。當COM需要marchal時,他首先通過QueryInterface看你是否支援IMarshal介面,如果你實現了該介面,也就是說,由你控制了你的COM的所有參數和傳回值的打包、解包的方法模式。

 

代理和存根dll的建立

       使用工具MIDL,對一個IDL檔案,MIDL會分析自動產生相應的代理/存根 DLL的相關檔案。

怎麼使用代理和存根

       對於你來說代理和存根的使用是透明的,你根本不用去關心如何使用他們,com庫會知道怎麼做。

      

    [ 註:本文中的圖均取自MSDN ]

       歡迎你閱讀此文,並留下寶貴的意見,討論會讓問題瞭解更加得深入,如果你要引用該文,請留下我的名字。 謝謝大家,共同進步。

如何組建代理程式/存根dll 

1.編譯idl 檔案,產生*_i.h、*_i.c、*_p.c、dlldata.c 和 *ps.def 檔案。

*.h為介面說明標頭檔;

*_p.c為介面代理和存根的實現檔案;

*_i.c為定義所有GUID描述符的檔案;

dlldata.c包含代理/存根程式的入口函數及類廠所需的資料結構。


如果沒有.def檔案,也可以自己編輯一個。格式如下:

      

LIBRARY      "testProxy.dll"


EXPORTS

    DllGetClassObject       @1  PRIVATE

    DllCanUnloadNow         @2  PRIVATE

    GetProxyDllInfo         @3  PRIVATE

    DllRegisterServer       @4  PRIVATE

    DllUnregisterServer     @5  PRIVATE


2. 建立一個新的win32應用程式:



程式類型為dll:



3. 加入上述五個檔案;

4.設定工程編譯屬性:

1)在Preprocessor Definitions 中加入:REGISTER_PROXY_DLL

2)在Linker->Input->Module Definition file指定模組定義檔案路徑:*ps.def;

3)在 Linker->Input->Additional Dependencies中加入:rpcrt4.lib uiid.lib

5.編譯,如果出現如下錯誤:

fatal error C1189: #error :  You need a Windows 2000 or later to run this stub because it uses these features:

在Preprocessor Definitions加入:_WIN32_WINNT=0x0500v

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.