在客户端需要调用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,但是还是能够实例化接口对应的类。

COM对象创建过程的更多相关文章

  1. Java中对象创建过程

    本文介绍的对象创建过程仅限于普通Java对象,不包括数组和Class对象. 1.类加载检查 虚拟机遇到一条new指令时,首先去检查该指令的参数能否在常量池中定位到一个类的符号引用,并且检查这个符号引用 ...

  2. Java中类加载过程和对象创建过程

    类加载过程: 1, JVM会先去方法区中找有没有相应类的.class存在.如果有,就直接使用:如果没有,则把相关类的.class加载到方法区 2, 在.class加载到方法区时,会分为两部分加载:先加 ...

  3. java基础---类加载和对象创建过程

    类中可以存在的成员: class A{ 静态成员变量: 非静态成员变量: 静态函数: 非静态函数: 构造函数 A(..){...} 静态代码块 static{...} 构造代码块 {...} } 类加 ...

  4. java类加载、对象创建过程

    类加载过程: 1, JVM会先去方法区中找有没有相应类的.class存在.如果有,就直接使用:如果没有,则把相关类的.class加载到方法区 2, 在.class加载到方法区时,会分为两部分加载:先加 ...

  5. JBPM TaskInstance 对象创建过程

    对象获得过程如下: 获得对象工厂--->工厂创建代理对象 TaskMgmtInstance tmi = executionContext.getTaskMgmtInstance(); TaskI ...

  6. OC对象创建过程

    在利用OC开发应用程序中,须要大量创建对象,那么它的过程是什么呢? 比方:NSArray *array = [[NSArrayalloc] init]; 在说明之前,先把OC的Class描写叙述一下: ...

  7. Java内存区域与对象创建过程

    一.java内存区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区域则 ...

  8. 【原创】Python 对象创建过程中元类, __new__, __call__, __init__ 的处理

    原始type: type是最原始的元类,其__call__方法是在你使用" t_class = type(classname_string, base_classes_tuple, attr ...

  9. 通过ORM模型看python对象创建过程

    简易django ORM模型如下所示: #!/usr/bin/env python # encoding: utf-8 """ @version: 1.0 @author ...

随机推荐

  1. Jconsole 工具介绍和使用方法

    http://chain.blog.163.com/blog/static/14084852320117934024410/ JConsole是一个基于JMX的GUI工具,JDK自带小工具     h ...

  2. 数据结构(Java语言)——Stack简单实现

    栈是限制插入和删除仅仅能在一个位置上进行的表.该位置是表的末端,叫做栈的顶top.对栈的基本操作有进栈push和出栈pop,前者相当于插入.后者这是删除最后插入的元素. 栈有时又叫先进先出FIFO表. ...

  3. pooler [转]

    pooler和poolboy都是用erlang写的管理进程池的库. pooler/poolboygithub : seth/pooler · GitHubgithub : devinus/poolbo ...

  4. 解决Oracle用户被锁定的方法

    解决Oracle用户被锁定的方法 1,cmd控制台: 使用sqlplus 命令:sqlplus sys/密码@ip/orcl as sysdba; 2,先设置具体时间格式,以便查看具体时间 SQL&g ...

  5. Kali安装OCI8 for metasploit Oracle login

    ps:安装了好久,最好才发现很简单,步骤记录下吧 遇到oracle爆破登录的时候OCI8报错,如下图 安装oracle 前面关于oracle client的安装就看官方文档吧 http://dev.m ...

  6. Windows上搭建Kafka

    搭建环境: 1,安装JDK JAVA_HOME: C:\Program Files (x86)\Java\jre1.8.0_60(这个是默认安装路径,如果安装过程中更改了安装目录,把更改后的路径填上就 ...

  7. HIbernate 级联删除

    在一对多的情形下如 Cinema - > Screen; 1.正常在不设置级联(casCade)的情况下 删除一的一方(Cinema)会报外键关联异常 (Screen 中包含Cinema的外键) ...

  8. 云服务器 ECS Linux CentOS 修改内核引导顺序

    由于 CentOS 7 使用 grub2 作为引导程序,所以和 CentOS 6 有所不同,并不是修改 /etc/grub.conf 来修改启动项,需要如下操作: 1. 查看系统内部有多少个内核: c ...

  9. a positive definite matrix

    https://en.wikipedia.org/wiki/Definite_quadratic_form https://www.math.utah.edu/~zwick/Classes/Fall2 ...

  10. samba服务器的搭建和配置

    案例: 公司有两个部门, sales / market . 分别有成员 jack / tom 和 zhang / shen . 公司需求是这样的, 本部门资料禁止其他部门访问, 本部门成员之间不能干扰 ...