进程透明性
不管是进程内组件还是进程外组件,客户程序可以使用一致的方法创建COM对象
对于进程外组件,创建成功后,可以用返回的对象接口指针调用对象的成员函数,由于客户程序和组件对象不是同一个进程空间中,所以接口的调用是间接进行的,但是客户程序调用接口函数的时候如果调用本进程内的函数一样。
进程外组件的调用方法:
列集:是指客户进程可以透明地调用另一进程中的对象成员函数的一种参数处理机制。
列集处理过程包括自定义列集法和标准列集法
自定义列集法又称基本列集法,其列集过程完全由对象自身控制,对象指定其代理对象的CLSID,代理对象控制了所有接口的列集、散集以及代理对象和存根代码间的跨进程通信过程。
标准列集法由COM提供缺省的代理对象、存根代码以及一套标准的列集方法,用于处理常用数据类型的列集和散集
标准列集法是自定义列集法的一个特例,但自定义列订法的列集过程完全由对象自身控制。
列集
类厂对象的列集过程:
CoMarshalInterfac函数流程分解:
函数首先向对象请求IMarshal接口指针,如果对象实现了IMarshal接口,则对象使用自定义列集方法,否则使用标准列集方法。
1. 调用 IMarshal接口的成员函数GetUnmarshalClass获取对象的CLSID,如果对象没有实现IMarshal接口,则指定使用COM提供的缺省代理对象,其CLSID为CLSID_StdMarshal.
2. 调用IMarshal接口成员函数GetMarshalSizeMax函数确定列集数据包可能的最大值,并分配一定的空间。(列集信息的传输由服务控制管理器—SCM控制)
3. 调用IMarshal接口成员函数MarshalInterface建立列集数据包
服务控制管理器(SCM):使用列集环境来描述进程间所存在的障碍或通道,可能的值如下
MSHCTX_NOSHAREDMEM:不能使用共享内存作为数据传输方式
MSHCTX_DIFFERENTMACHINE:两个进程可能在不同的机器上
这些值由CoMarshalInterface函数及IMarshal::GetUnmarshalClass中的的dwDestContext参数提供
CoMarshalInterface函数及IMarshal::GetUnmarshalClass中的mshlflags参数指示了列集的目的:
MSHLFLAGS_NORMAL:列集马上用于连接一个客户进程
MSHLFLAGS_TABLESTRONG、MSHLFLAGS_TABLEW