5.进程内组件和进程外组件
进程内组件:使用动态链接库的形式实现,客户程序调用组件程序的服务时,会把组件程序装入到自己的进程中,客户程序和组件程序运行在同一个进程空间中,成为进程内组件。用DLL构造出来的COM组件运行在客户程序进程中,客户程序与组件之间通过直接函数调用的方法进行交互,运行效率很高;但反过来组件程序直接运行在客户进程中,组件程序中的严重错误有可能引起客户进程的崩溃。
进程外组件:组件程序实现的另外一种形式是EXE程序,这种组件程序在被调用时有其自己的进程空间,组件程序与客户程序运行在各自的进程空间,成为进程外组件。
应用调用其他进程服务的顺序图:
对比上图,进程外组件与客户程序交互结构图:
如上图,客户程序只与同一进程的代理DLL中对象打交道,组件程序只与同一进程中的存根DLL打交道。代理DLL和存根DLL除了完成LPC调用之外,还需要对参数和返回值进行翻译和传递:
(1) 客户程序调用的参数,经过代理DLL的处理,把参数以及其他的一些调用信息组装成一个数据包传递给组件程序,这个过程成为参数列集;
(2) 组件进程接收到数据包之后,进行解包操作,把参数信息提取出来,这个过程成为散集;
(3) 进行实际的组件接口功能调用;
(4) 函数的返回值和输出参数在返回时在存根DLL中列集;
(5) 代理DLL中散集操作;
(6) 散集后的结果返回给客户程序;
(7) 如此完成一次功能调用。
6.通过注册表管理COM对象
系统注册表时一个全操作系统范围公用的信息仓库,所以客户程序和组件程序都可以方位系统注册表。组件程序把它所实现的COM对象的信息以及接口信息都保存到注册表中,称为组件注册;客户程序在创建组件对象时,也需要直接或间接地访问注册表中的信息,通常,组件对象的创建工作由COM库来完成,COM库所进行的很多操作都要依赖系统注册表提供的信息才能完成。
7.类厂
类厂,是COM对象的生产基地,COM库通过类厂创建COM对象,对应每个COM类有一个专门由于该COM类对象创建操作的类厂。类厂本身也是一个COM对象,它支持一个特殊的接口IClassFactory其定义如下:
CreateInstance用于创建对应的COM对象,因为每个类厂针对特定的COM类对象,所以其知道该怎样创建COM对象。LockServer函数用于控制组件的生存周期。
类厂创建COM对象,那也是COM对象的类厂又是如何创建的呢?答案是组件程序实现的引出函数DllGetClassObject。
COM库与类厂的交互
COM库常用的三个API函数:CoGetClassObject,CoCreateInstance和CoCreateInstanceEx。后两个函数实现功能一样都是创建COM对象实例,只不过后者可一次获取多个接口指针。
如下为客户程序调用COM库创建组件对象的顺序图:
8.COM库
如下为COM库常用函数:
9.COM实现过程
进程内组件与客户的写作过程: