8跨进程特性

上传人:野鹰 文档编号:2870586 上传时间:2017-07-28 格式:PPT 页数:24 大小:131KB
返回 下载 相关 举报
8跨进程特性_第1页
第1页 / 共24页
8跨进程特性_第2页
第2页 / 共24页
8跨进程特性_第3页
第3页 / 共24页
8跨进程特性_第4页
第4页 / 共24页
8跨进程特性_第5页
第5页 / 共24页
点击查看更多>>
资源描述

《8跨进程特性》由会员分享,可在线阅读,更多相关《8跨进程特性(24页珍藏版)》请在金锄头文库上搜索。

1、1,八. COM跨进程特性,进程外组件进程内COM对象的缺陷进程外组件的使用列集 列集的概念接口指针的列集标准列集过程总体结构存根代理接口列集器ORPC通道标准列集的实现自定义列集IMarshal接口例子,2,1.进程外组件,1.1 进程内COM对象的缺陷1.缺乏错误隔离. 对象的运行时错误将直接引起客户程序的崩溃. 2.安全环境共享 对象在客户进程中,使用的是客户进程的安全环境与权限. 这意味着特权客户程序创建的对象可以进行危险的操作; 较低权限的用户创建的对象可能无法访问一些重要的资源,从而无法达到计划的目的. 3. 很难实现分布式计算 进程内的对象使得“多个客户进程共享同一个对象”非常困

2、难.进程外的COM组件也是实现DCOM的基础.(另外一台机器上的进程.) 无论哪种方式(进程内,进程外,远程)对客户而言,是透明的.进程外的COM对象具有重要的意义.,3,进程外COM组件的实现以exe的形式存在.可以独立执行.它 不会引出函数DllRegisterServer 和DllUnregisterServer. 相反,它执行时会检测命令行中是否有参数/ RegServer或/UnregServer, 以决定是否对注册表进行注册(注销). 注册表中它所支持的COM对象项中用LocalServer32键代替InprocServer32键.进程外组件没有输出DllGetClassObjec

3、t以让客户程序得到类厂对象,相反当客户调用CoGetClassObject创建类厂对象时:在CoGetClassObject函数内部,它找到EXE组件的程序位置后,发现是一个进程外组件, 于是启动组件进程,然后等待.组件进程启动后(使用了/Embedding参数),调用CoInitialize初始化,创建所有的类厂,调用CoRegisterClassObject把类厂注册到COM中.客户进程得到了组件的类厂信息,创建类厂,然后创建对象.组件程序没有引出DllCanUnloadNow函数. 但是其判断是否可以卸载的条件与之相类似. 组件进程退出时,使用CoRevokeClassObject函数在

4、COM库中注销掉其所支持的类厂. CoRegisterClassObject与 CoRevokeClassObject要配对使用,以保证COM信息的一致性.进程外组件与客户进程之间使用RPC进行通讯.如下图所示:,1.2 进程外组件的使用,4,进程外组件与客户进程之间使用RPC进行通讯. 在客户进程与组件对象之间是代理对象和存根对象. 代理和存根直接使用RPC. 这里的RPC是经过了扩展的RPC, 称为ORPC. 在ORPC中, 调用请求和返回结果要经过列集和散集的过程. 其定义如下.,2. 列集,5,列集(marshaling) 和散集(unmarshaling)marshal的字典含义:编

5、组、调度、引导、安排整顿、配置、汇集、排列、集合定义:是指客户进程可以透明地调用另一进程中的对象成员函数的一种参数处理机制在调用过程中如果涉及到数值或指针的传递,则列集过程如下:数值: 比如一个32位整数, 把四个字节的数据顺序装入到字节流中即可.地址: 一个进程中的地址对另一个进程没有意义. 因此,列集时是把地址中的数据取出来封装到数据包中,散集时,在客户进程中分配一块内存数据包中的数据拷贝到内存中,然后返回内存地址.接口指针: 实际上列集更重要的工作在于获取对象的接口指针.客户程序的一个有效接口指针代表客户进程到组件进程的一个连接.列集一个接口指针远比一个一般的指针要复杂. 以下讨论的列集

6、一般都指接口指针的列集.,2.1 列集的概念,6,2.2 接口指针的列集,接口指针列集的结果是把它变为一个可以被传输的字节流,字节流的内容唯一地标识了对象和对象所处的环境. (即套间 Apartment 见后, 现在可以理解为运行环境)列集过程分为两种:标准列集和自定义列集.由于列集要使用到底层的传输协议,而这些代码往往对所有的对象而言是类似的,所以COM提供了标准列集法, 凡是没有特别指明的,都是使用这种方法. 为了效率等因素,对象可以选择自己控制底层的通讯.这时称为自定义列集法.标准列集方式下的接口指针列集数据流. 见下图:,7,其中OXID代表了对象的运行环境(套间). 代理需要使用此O

7、XID来解析成网络或者IPC(进程间通讯)的地址,以便与对象的套间进行联系. OXID的解析工作由OXID解析器(OXID Resolver, OR)完成. OR是RPCSS服务的一部分.接口指针的列集过程是由COM库函数CoMarshalInterface完成的:,8,HRESULT CoMarshalInterface( IStream *pStm, /列集数据的存放位置,是一个流.底层介质可以是磁盘,内存,或自定义的介质. 见结构化存储. REFIID riid, /列集指针的类型 IUnknown *pUnk, /列集指针,当然它应该是riid类型的. DWORD dwDestCont

8、ext, /目标环境. void *long pvDestContext, /保留. DWORD mshlflags /常规列集还是表格列集(写到一个全局的接口表中,可以被多次散集);散集过程由函数CoUnmarshalInterface完成HRESULT CoUnmarshalInterface( IStream *pStm, /包含有列集内容的流REFIID riid, / 散集指针类型void * * ppvObj /存放散集指针的位置);一般而言,除非在进程内(而且套间类型相吻合),散集的接口不是原来的接口本身,而是一个代理.,9,3 标准列集过程,3.1 总体结构如果一个对象没有实现

9、IMarshal接口,那么它的引用都是按照标准列集方式进行.列集所使用的通讯协议: COM使用ORPC (Object Remote Procedure Call)来进行远程的通讯. COM对MS RPC其进行了扩充,以支持面向对象的调用。称为ORPC。 ORPC使用标准的RPC数据包,附加上专用于COM的信息,如接口指针标识符。在ORPC数据包经过列集后的数据按照NDR格式保存(网络数据表示法Network Data Representation)(CORBA使用CDR Common Data Representation,Web服务使用XML)。标准列集的通讯机制如下图:,10,标准列集的

10、proxy和stub结构,11,当CoMarshalInterface第一次确定对象希望使用标准列集时, 就创建一个特殊的COM对象: “存根管理器”. (Stub Manager). 存根管理器与COM对象一一对应, 被对象标识符OID标识(见接口的列集数据图). 并且拥有一个对COM对象的引用.可以理解为一个进程内的客户.存根管理器并不知道如何处理ORPC请求.它针对每个COM接口管理一个“接口存根”对象(interface stub).接口存根是用IPID来标识的. 接口存根知道关于这个接口的所有细节,它知道如何把ORPC请求消息中出现的所有in参数都散集出来,并且调用实际对象中的方法,

11、然后把HRESULT结果和所有out参数列集到ORPC相应消息中去. 接口存根也有一个对COM对象的引用.,3.2 存根,12,接口存根实现IRpcStubBuffer接口class IRpcStubBuffer : public IUnknown HRESULT Connect(IUnknown *pUnkServer) = 0; /把接口存根与目标COM对象联系起来 void Disconnect() = 0; /释放对象 HRESULT Invoke(RPCOLEMESSAGE *pMessage, IRpcChannelBuffer *pChannel) = 0;/当ORPC请求到达对

12、象一方时,COM库会调用Invoke方法, *pMessage包含所有经过列集的in参数,也要利用RPC通道把处理结果发送回去 IRPCStubBuffer* IsIIDSupported(REFIID iid) = 0; ULONG CountRefs() = 0; HRESULT DebugServerQueryInterface(void *ppv) = 0; void DebugServerRelease(void *pv) = 0;,13,当CoUnmarshalInterface把一个标准列集得到的对象引用散集出来的时候,它会创建一个“代理管理器”(proxy manager).

13、和存根管理器一样,它也不懂COM接口的任何知识,它也要针对每一个接口创建一个“接口代理”对象(Interface proxy),并且把这些对象都聚合在其内部.让客户感觉所有的接口都是从这个代理管理器上实现的. 代理管理器实现了IUnkown的三个函数.并且对AddRef和Release进行了优化处理,使得这些操作非到最后,只是增减本地的一个引用计数.这样以减少网络开销.接口代理把客户的调用请求转换成为ORPC请求消息(列集in参数).并且把ORPC相应消息中的out消息和HRESULT散集出来,返回给客户进程.,3.3 代理,14,每个接口代理实现IRpcProxyBuffer接口.class

14、 IRpcProxyBuffer : public IUnknown HRESULT Connect(IRpcChannelBuffer *pRpcChannelBuffer) = 0; void Disconnect() = 0;接口代理管理器通过这个接口把接口代理与RPC通道连接起来,Connect方法把RPC通道保存起来接口代理接到方法请求后,通过IRpcChannelBuffer接口的GetBuffer和SendReceive方法处理远程方法调用,15,接口代理和接口存根分别由代理管理器和存根管理器创建.它们共享同一个CLSID. 包含两个分叉实现的实体称为接口列集器(Interfac

15、e marshaler). 接口列集器的类厂没有实现接口IClassFactory (有一个成员函数CreateInstance,以创建对应的COM对象) ,相反,它实现了接口 IPSFactoryBuffer. uuid(D5F569D0-593B-101A-B569-08002B2DBF7A),local,object interface IPSFactoryBuffer : IUnknown HRESULT CreateProxy( in IUnknown *pUnkOuter, / 代理管理器指针 in REFIID riid, /请求的远程接口指针的IID out IRpcProxyBuffer *ppProxy, /输出接口代理指针 out void *ppv ); / 远程接口指针 HRESULT CreateStub( in REFIID riid, / 请求的远程接口指针IIDin IUnknown *pUnkServer, / 实际对象指针out IRpcStubBuffer *ppStub ); / 输出接口存根指针 接口列集器的CLSID存放在注册表中.,

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号