什么是代理和存根 ?
打個比方,,你到自動取款機(jī)上去取款,;你就是客戶,取款機(jī)就是你的代理,;你不會在乎
錢具體放在那里,,你只想看到足夠或更多的錢從出口出來(這就是com的透明性)。你同銀行之間的操作完全是取款機(jī)代理實現(xiàn),。 你的取款請求通過取款機(jī),,傳到另一頭,銀行的服務(wù)器,,他也沒有必要知道你在哪兒取錢,,他所關(guān)心的是你的身份,和你取款多少,。當(dāng)他確認(rèn)你的權(quán)限,,就進(jìn)行相應(yīng)的操作,,返回操作結(jié)果給取款機(jī),,取款機(jī)根據(jù)服務(wù)器返回結(jié)果,從保險柜里取出相應(yīng)數(shù)量的錢給你,。你取出卡后,,操作完成。 取款機(jī)不是直接同服務(wù)器連接的,,他們之間還有一個“存根”,,取款機(jī)與存根通信,服務(wù)器與存根通信,。從某種意義上說存根就是服務(wù)器的代理,。
圖1 組件間通信
如上圖兩個組件之間不是直接通信,而是通過代理和存根來之間的通信來間接實現(xiàn)的。圖中的channel是com庫的一部分,。
COM里,,只有進(jìn)程外組件才會用到代理(proxy)和存根(stub)。
代理在客戶的進(jìn)程內(nèi)創(chuàng)建,,存根在組件com對象的進(jìn)程中創(chuàng)建,。 每個接口的每個函數(shù)都有自己的代理和存根。
為什么要用代理和存根 ,?
客戶為什么要用代理和存根,,而不直接同對象連接呢? 給你一個理由,,對客戶來說,,他與所有com對象的連接都是通過指針來調(diào)用的, 而對服務(wù)來說,,調(diào)用對象的接口函數(shù)也是通過指針來完成的,,然而,指針只有在同一進(jìn)程內(nèi)才會有效,。這樣,,代理和存根為了完成這個使命也就產(chǎn)生了。
代理和存根的作用不只這些,,他還要打包所有的參數(shù)(包括接口指針),,產(chǎn)生 RPC(遠(yuǎn)程進(jìn)程調(diào)用),通向另一個進(jìn)程,,或者對象運(yùn)行所在的另一臺機(jī)器,。
圖2 代理的結(jié)構(gòu)
上圖所顯示的代理結(jié)構(gòu)支持參數(shù)的標(biāo)準(zhǔn)列集。每個接口的代理實現(xiàn)了IRpcProxyBuffer接口,,用于內(nèi)聚各個部分之間的相互通信,。當(dāng)代理準(zhǔn)備把已列集的參數(shù)傳遞過進(jìn)程邊界時,,他調(diào)用IRpcChannelBuffer 接口的方法(該接口由channel實現(xiàn))。channel調(diào)用RPC運(yùn)行庫使數(shù)據(jù)傳輸?shù)侥康牡亍?/span>
圖3 存根的結(jié)構(gòu)
如上圖所示,,每個接口的存根被連接到對象的相應(yīng)接口上,。chnnel分發(fā)傳入的消息到適當(dāng)?shù)慕涌诘拇娓K械慕M件通過IRpcChannelBuffer接口與chnnel交流,,這個接口提供了與RPC運(yùn)行庫的連接,。
列集(marshalling)
說到代理和存根,,自然少不了列集,什么是列集,?
列集,,對函數(shù)參數(shù)進(jìn)行打包處理得過程,因為指針等數(shù)據(jù),,必須通過一定得轉(zhuǎn)換,,才能被另一組件所理解,列集完成后,,RPC調(diào)用就會產(chǎn)生,。可以說列集是一種數(shù)據(jù)格式的轉(zhuǎn)換方法,。
列集有3種方式:
1. 類型庫列集
它可以列集與OLEAUTOMATION兼容的任何接口,,意思是你的接口的返回值必須是HRESULT,所使用的參數(shù)的類型也應(yīng)該是與C++的VARIANT結(jié)構(gòu)兼容,。
2. 通過創(chuàng)建Stub / proxy DLL
這個DLL的源代由MIDL產(chǎn)生,。你必須在服務(wù)器和客戶機(jī)上都注冊這個DLL(這是標(biāo)準(zhǔn)的marshal 方式)使用吃方法時,最好把stub / proxy代碼編譯作為一個獨立的組件,。
3. 自定義marshaling
自定義marshal要求在你的組件中必須實現(xiàn)IMarshal接口,。當(dāng)COM需要marchal時,他首先通過QueryInterface看你是否支持IMarshal接口,,如果你實現(xiàn)了該接口,,也就是說,由你控制了你的COM的所有參數(shù)和返回值的打包,、解包的方法模式,。
代理和存根dll的建立
使用工具MIDL,對一個IDL文件,,MIDL會分析自動產(chǎn)生相應(yīng)的代理/存根 DLL的相關(guān)文件,。
怎么使用代理和存根
對于你來說代理和存根的使用是透明的,你根本不用去關(guān)心如何使用他們,,com庫會知道怎么做,。