在客户端需要调用COM组件时,通常调用windowAPI函数:

STDAPI CoCreateInstance(
REFCLSID rclsid, //创建的Com对象的类标识符(CLSID)
LPUNKNOWN pUnkOuter, //指向接口IUnknown的指针
DWORD dwClsContext, //运行可执行代码的上下文
REFIID riid, //创建的Com对象的接口标识符
LPVOID * ppv //用来接收指向Com对象接口地址的指针变量
);
来返回所需函数的接口ppv。其实这个函数是一个封装函数,共封装了创建COM对象的两个步骤。
 
一、类工厂
类工厂(IClassFactory),是用来生成类对象实例(即给类分配内存)并返回所请求接口(上面的ppv参数)的一个类。
COM组件中的类与类工厂是分离的。从本质上讲,类工厂类生育了我们所需要的那个类。
如何办到的呢?
类工厂有个函数 HRESULT CreateInstance(LPUNKNOWN pUnk,REFIID riid,void** ppv),该函数传入所需要的类的那个接口的IID(riid),并返回那个接口ppv.
在这个函数内部,所需类是通过new函数直接创建的,然后调用这个类的QuryInterface()函数返回那个接口ppv的。
因此,最终类还是通过new函数创建的,只是把这个过程隐藏了,不对客户公开。
二、DllGetClassObject函数
该函数用来创建类工厂实例,并返回类工厂接口指针。通过这个指针调用CreateInstance()就实现了获取所需接口的指针。
STDAPI DllGetClassObject(REFCLSID rclsid,REFIID riid, LPOVID* ppv)
rclsid:组件的GUID
riid:类工厂的GUID
ppv:类工厂的接口指针
因此总的顺序就是:
CoCreateInstance调用CoGetClassObject()加载COM组件,后者调用DllGetClassObject(clsid,id_ifactory,ppv_factory)生成类工厂指针,类工厂指针再调用CreateInstance()生成类实例,返回接口指针。
 
至于为什么要通过类工厂创建组件对象实例,原因有二:
1.类工厂创建对象是对对象创建过程的一种统一封装,实现不同语言创建COM组件统一性。
2.COM对象可以位于客户进程之外。
 
至于接口和类之间是怎样一一映射的,可能是通过他们的GUID建立起来的映射关系。因为类也有自己的GUID,因此类工厂只提供了接口的GUID,但是还是能够实例化接口对应的类。

最新文章

  1. Html--表单练习
  2. ListView的联动实现
  3. Java JVM类加载机制
  4. hiho #1309 任务分配
  5. 实战:ORACLE SQL Performance Analyzer
  6. html-----020----事件
  7. JAVA基于AE调用GP实现泰森多边形
  8. Altium designer使用技巧集(1)
  9. WEB ICON 的探讨
  10. WCF技术剖析之六:为什么在基于ASP.NET应用寄宿(Hosting)下配置的BaseAddress无效
  11. LeetCode算法题-Range Addition II(Java实现)
  12. Java多线程核心技术(四)Lock的使用
  13. hdu 6393 Traffic Network in Numazu (树链剖分+线段树 基环树)
  14. 2018 ACM 网络选拔赛 南京赛区
  15. jquery基础学习之动画篇(四)
  16. 约瑟夫环(Joseph)的高级版(面向事件及“伪链表””)
  17. js - 如何使子元素阻止继承父元素事件
  18. Autofs
  19. 对simhash算法的一些思考
  20. Apache Commons CLI

热门文章

  1. 何为SLAM
  2. javascript判断智能终端信息
  3. P13在O(1)时间内删除链表结点
  4. php计算两个经纬度地点之间的距离(转)
  5. 11-利用session校验图片认证码
  6. centOS下安装ejabberd
  7. error_logger 爆炸
  8. MySQL中使用INNER JOIN来实现Intersect并集操作
  9. Eclipse中执行Tomcat源代码
  10. TP框架---thinkphp修改删除数据