1、 为什么要用COM
OO vs. COM ——
重用的方法不同
(
1
)
类库
——
类库
的重用基于源
码
的方式
①
限制了
编
程
语
言
②
每
次都必
须
重新
编译
(
2
)
DLL ——
①
函数重名
问题
②
各
编译
器
对
C
++函数的名称修
饰
不兼容
问题
(也可以用
extern "C"
;来
强调
使用
标
准的
C
函数特性,
关闭
修
饰
功能,但
这样
也
丧
失了
C
++的重
载
多
态
性功能)
③
路径
问题
④ DLL
与
EXE
的依
赖问题
2
、
COM
组
件
实际
上是一个
C++
类
,而接口都是
纯
虚
类
。
组
件从接口派生而来。
COM
组
件是以
C++
为
基
础
的,特
别
重要的是虚函数和多
态
性
的概念,
COM
中所有函数都是虚函数,都必
须
通
过
虚函数表
VTable
来
调
用。
3
、
COM
组
件有三个最基本的接口
类
,分
别
是
IUnknown
、
IClassFactory
、
IDispatch
。
COM
规
范
规
定任何
组
件、任何接口都必
须
从
IUnknown
继
承,
IUnknown
包含三个函数,分
别
是
QueryInterface
、
AddRef
、
Release
。
这
三个函数是无比重要的,而且它
们
的排列
顺
序也是不可改
变
的。
IClassFactory
的作用是
创
建
COM
组
件。
每
个
组
件都必
须
有一个与之相
关
的
类
厂,
这
个
类
厂知道怎
么样创
建
组
件,当客
户请
求一个
组
件
对
象的
实
例
时
,
实际
上
这
个
请
求交
给
了
类
厂,由
类
厂
创
建
组
件
实
例,然后把
实
例指
针
交
给
客
户
程序。
IClassFactory
最重要的一个函数就是
CreateInstance
,
顾
名思
议
就是
创
建
组
件
实
例。
IDispatch
叫做
调
度接口。
调
度接口把
每
一个函数
每
一个属性都
编
上号,客
户
程序要
调
用
这
些函数属性的
时
侯就把
这
些
编
号
传给
IDispatch
接口就行了,
IDispatch
再根据
这
些
编
号
调
用相
应
的函数,
仅
此而已。
4
、
COM
组
件有三
种
,
进
程内、本地、
远
程。
对
于后两者情况必
须调
度接口指
针
及函数参数。
5
、
COM
组
件的核心是
IDL
。
6
、
COM
组
件的运行机制
IUnknown *pUnk=NULL;
IObject *pObject=NULL; CoInitialize(NULL); CoCreateInstance(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IUnknown, (void**)&pUnk); pUnk->QueryInterface(IID_IOjbect, (void**)&pObject); pUnk->Release(); pObject->Func(); pObject->Release(); CoUninitialize(); |
这
就是一个典型的
创
建
COM
组
件的框架,不
过
我的
兴
趣在
CoCreateInstance
身上,
让
我
们
来看看它内部做了一些什
么
事情。以下是它内部
实现
的一个
伪
代
码
:
CoCreateInstance(....)
{
.......
IClassFactory *pClassFactory=NULL; CoGetClassObject(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&pClassFactory); pClassFactory->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk); pClassFactory->Release();
........
}
|
这
段
话
的意思就是先得到
类
厂
对
象,再通
过类
厂
创
建
组
件从而得到
IUnknown
指
针
。
继续
深入一
步
,看看
CoGetClassObject
的内部
伪码
:
CoGetClassObject(.....)
{
//
通
过查
注册表
CLSID_Object
,得知
组
件
DLL
的位置、文件名
// 装入 DLL 库 // 使用函数 GetProcAddress(...) 得到 DLL 库 中函数 DllGetClassObject 的函数指 针 。 // 调 用 DllGetClassObject
}
|
DllGetClassObject
是干什
么
的,它是用来
获
得
类
厂
对
象的。只有先得到
类
厂才能去
创
建
组
件
.
下面是
DllGetClassObject
的
伪码
:
DllGetClassObject(...)
{
......
CFactory* pFactory= new CFactory; // 类 厂 对 象 pFactory->QueryInterface(IID_IClassFactory, (void**)&pClassFactory); // 查询 IClassFactory 指 针 pFactory->Release();
......
}
|
CoGetClassObject
的流程已
经
到此
为
止,
现
在返回
CoCreateInstance
,看看
CreateInstance
的
伪码
:
CFactory::CreateInstance(.....)
{
........... CObject *pObject = new CObject; // 组 件 对 象 pObject->QueryInterface(IID_IUnknown, (void**)&pUnk); pObject->Release(); ........... } |
7
、
注册表
问题