在客户端需要调用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. c# 访问Mysql

    下载Connector/Net驱动程序,并安装. 通过MySQLConnection对象来连接数据库,连接MySQL的程序的最前面需要引用MySql.Data.MySqlClient. using M ...

  2. 代理server的概要知识

    技术支持请留言:http://www.lcpower.cn 一.什么是代理server? 代理server英文全称是Proxy Server.其功能就是代理网络用户去取得网络信息.形象的说:它是网络信 ...

  3. 阿里云 RDS实例间的数据迁移

    使用数据传输DTS可以实现两个RDS实例间的数据迁移.对于支持增量迁移的存储引擎,还可以使用DTS在源RDS实例不停服的情况下,将数据迁移到目标RDS实例.目前对于RDS不同存储引擎,只支持同构迁移( ...

  4. 设计模式之Protocol实现代理模式

    使用场合 使用步骤 不使用protocol实现代理 使用protocol实现代理 一.使用场合 A想让B帮忙,就让B代理 A想通知B发生了一些事情,或者传一些数据给B 观察者模式 二.使用步骤 定义一 ...

  5. linux下编译ffmpeg 引入外部库x264

    Found no assembler Minimum version is nasm-2.13 If you really want to compile without asm, configure ...

  6. Enumerate Combination C(k, n) in a bitset

    Suppose n<=32, we can enumerate C(k, n), with bits representing absence or presence, in the follo ...

  7. 【转】win7 任务计划 任务映像已损坏或篡改(异常来自HRESULT:0x80041321)

    请这样操作:1. 以管理员身份运行命令提示符并执行命令chcp 437schtasks /query /v | find /i "ERROR: Task cannot be loaded:& ...

  8. Android API Guides---Storage Access Framework

    存储訪问架构 Android 4.4系统(API级别19)推出存储訪问框架(SAF).新加坡武装部队变得很easy,为用户在其全部自己喜欢的文件存储提供商的浏览和打开文档,图像和其它文件.一个标准的, ...

  9. VC项目文件说明

    .dsp   项目参数配置文件,这个文件太重要,重点保护对象.. .dsw   工作区文件,重要性一般,因为它信息不我,容易恢复.   以下文件在项目中是可丢弃的,有些文件删除后,VC会自动生成的. ...

  10. android菜鸟学习笔记12----Android控件(一) 几个常用的简单控件

    主要参考<第一行代码> 1.TextView: 功能与传统的桌面应用开发中的Label控件相似,用于显示文本信息 如: <TextView android:layout_width= ...