《MFC Windows程序设计》第18章(1):COM

来源:互联网 发布:安卓卫星电视软件 编辑:程序博客网 时间:2024/05/18 02:33

1、COM介绍

COM即组件对象模型(Component  Object  Model),它使我们可以用任意一种编程语言编写在任意编程语言中都能使用的类。

COM对象的“方法”被组织在“接口”中,并通过“接口指针”来调用它们。一个接口可以包含多个方法,意义相近的方法应该放到一个接口中,如若一个COM类中有Add、Subtract、CheckSpelling等方法,则应该将Add和Subtract方法分配给接口IMath,将CheckSpelling分配给接口ISpelling。

COM对象包含了一百多个预定义接口,称为标准接口;用户定义的接口称为自定义接口,如上面的IMath和ISpelling接口;COM接口名一般以大写字母“I”开头。

每一种COM对象都实现了一个IUnknown接口,该接口包含以下三个方法,而且所有接口自动包含了IUnknown的方法(COM规定用户创建的接口必须从IUnknown接口继承而来)。而通过IUnknown接口的QueryInterface方法可知:如果你已经有了一个接口,那么就可以从这个接口获得任何另一个接口。对于大多数接口而言,如果要请求一个IUnknown指针,它就会简单的返回指向另一个接口的指针。

接口标识IID唯一的标识了每一个接口,是一个128位的值。COM API函数CoCreateGuid可以生成IID。

COM类标识GUID也被称为类ID或CLSID

2、实例化COM对象

COM API中的“激活函数”用来实例化COM对象,其中最常用的是CoCreateInstance()函数,它用来创建COM对象实例,并获得指向对象接口的指针。函数原型:

WINOLEAPI CoCreateInstance(

                           IN REFCLSID rclsid,                //CLSID
                           IN LPUNKNOWN pUnkOuter,
                           IN DWORD dwClsContext,
                           IN REFIID riid,                           //IID
                           OUT LPVOID FAR* ppv          //保存指向对象接口的指针
                           );

可以通过指向对象接口的指针调用接口的方法,而接口的方法返回特定的32位值,称为HRESULT,用来指示函数执行成功还是失败。SUCCEEDED宏可以用来检测HRESULT码是否成功,FAILED宏用来检测HRESULT码是否失败。

eg:

//实例化一个CLSID为CLSID_Object的COM类,将指向对象的IMath接口的指针保存在pMath中IMath* pMath;HRESULT hr = CoCreateInstance(CLSID_Object, NULL, CLSCTX_SERVER, IID_IMath, (void**)&pMath);if(SUCCEEDED(hr)){//通过接口指针调用接口中方法,将结果保存在sum中int sum;pMath->Add(2, 3, &sum);}

CoCreateInstance()函数内部是先实例化一个“类对象”,然后再利用这个类对象去创建对象。大多数类对象都实现了一个特殊的接口:IClassFactory(IClassFactory2),实现IClassFactory的类对象称为“类工厂”,可以通过调用IClassFactory::CreateInstance方法来创建对象实例。

可以通过CoCreateInstance()来实例化的COM类称为对外可创建的COM类;而一些类没有CLSID和类工厂,它们通过new来实例化对象。

3、对象生存期

COM对象的内部引用计数记录了保存有指向对象接口指针的客户数量,当引用计数为0时,执行对象的删除操作。引用计数在调用AddRef()时递增,调用Release()时递减。

在任何提供对象接口指针的时候都会增加对象的引用计数,而接口指针不再使用的时候应该调用Release()减少对象的引用计数。

4、获得其它接口指针

前面我们知道IUnknown接口包含QueryInterface、AddRef、Release三个方法,QueryInterface方法可以获得指向其它接口的指针,而每个接口都自动包含了IUnknown的方法。 在调用CoCreateInstance()实例化对象后会获得一个接口指针,所以可以通过这个接口指针调用QueryInterface()获得指定接口的指针。eg:

IMath* pMath;HRESULT hr = CoCreateInstance(CLSID_Object, NULL, CLSCTX_SERVER, IID_IMath, (void**)&pMath);if(SUCCEEDED(hr)){//获得IID为IID_ISpelling接口的指针,pSpelling用来保存获得的接口指针ISpelling* pSpelling;hr = pMath->QueryInterface(IID_ISpelling, (void**)&pSpelling);if(SUCCEEDED(hr)){...pSpelling->Release();}pMath->Release();}
不存在可以枚举对象所有接口的COM函数。

5、COM服务器

在实例化COM对象时,必须知道在哪里可以找到实现对象的可执行文件,这个文件就叫COM服务器。COM服务器会给COM提供一个“类工厂”,COM会调用类工厂的CreateInstance方法来创建对象实例。注册表中的HKEY_CLASSES_ROOT \ CLSID部分所包含的信息将CLSID和可执行文件联系起来。

COM服务器具有两种类型:进程内类型(in-proc)和进程外类型(out-of-proc)。进程内类型服务器是DLL(动态链接库)类型的,其运行在于客户相同的地址空间里,调用in-proc对象速度快。进程外类型服务器是EXE类型的,其运行的地址空间与客户彼此隔离,可以彼此保护以防客户或out-of-proc对象其中一个崩溃。

分布式COM(DCOM)可以使进程外类型服务器存在于远程网络上(对于Windows NT 4.0 sp2,进程内类型服务器可以通过使用代理EXE程序来调用DLL的机制实现远程运行)。运行在同一设备的上的进程外类型服务器称为“本地服务器”,运行在远程机器上得进程外类型服务器称为“远程服务器”。

6、“名称解析代理”和“桩基模块”

7、OLE

OLE即对象链接和嵌入,是一种技术,通过COM来实现。它可以将一个程序创建的“内容对象”放入另一个程序创建的文档中。例如,将Excel创建的电子表格放到Word文档中,在这种情况下,Excel是OLE服务器,其提供链接或嵌入的内容对象即电子表格,Word是OLE容器,其用来管理内容对象。

8、Active Documents

Active Documents即活动文档,它是从CLE发展而来的基于COM的技术。Active Documents协议是对象链接与嵌入的超集,他允许Active Documents容器打开由Active Documents服务器创建的文档文件。例如,IE可以直接打开Word文档,实际上是IE通过COM接口与Word进行了会话,使用的仍然是Word。

9、ActiveX

首先是OLE,接下来是COM,然后才出现了ActiveX。Active X是一套基于COM的技术,用来使Internet更具有交互性。它包括ActiveX控件、ActiveX数据对象(ADO)、动态服务器页面(ASP)、Active Documents等。

ActiveX控件就是COM对象,管理ActiveX控件的应用程序被称为ActiveX控件容器,其要实现COM接口,而MFC为封装ActiveX和控件容器做了很多工作,提供了常备的COM的ActiveX控件接口的实现,大大简化了开发ActiveX控件的开发过程。












0 0
原创粉丝点击