com学习笔记+++

上传人:第*** 文档编号:34024088 上传时间:2018-02-20 格式:DOC 页数:29 大小:314.50KB
返回 下载 相关 举报
com学习笔记+++_第1页
第1页 / 共29页
com学习笔记+++_第2页
第2页 / 共29页
com学习笔记+++_第3页
第3页 / 共29页
com学习笔记+++_第4页
第4页 / 共29页
com学习笔记+++_第5页
第5页 / 共29页
点击查看更多>>
资源描述

《com学习笔记+++》由会员分享,可在线阅读,更多相关《com学习笔记+++(29页珍藏版)》请在金锄头文库上搜索。

1、COM 学习笔记 (一)初识 COMCOM-ComponentObject Model,组件对象模型。一向以难学著称,有人曾说过这样的话:世界上只有两个程序员真正理解 COM,他们都在微软工作。这句话虽然有点过,但基本上说出了 COM 确实有些难理解。不过,不用担心,本文并不探求多深多高的技术领域,而是带领大家浏览一下我们的 COM,就像本文的题目一样:初识 COM。首先,我们先来了解一下有关 COM 的概念:COM(Component Object Model, 组件对象模型 )是微软公司的最高级的、包罗万象的二进制通信规范,用于软件组件间跨越多个进程、机器、硬件和操作系统进行互操作。下面我

2、们来看看 COM 的一些特点:在 COM 中,应用程序不是通过诸如 ShowWindow()的 API 函数进行操纵。程序是由对象组成的,对象向外提供一个或多个接口。接口是一组相关的函数,函数操作他们所属的对象。不能直接访问对象中的数据,而只能通过对象的接口函数访问。学过 C+和数据结构的人应该对上述说法并不陌生。在 COM 中,没有指向对象的指针这种东西,有的只是指向对象接口的指针。实际上,是指向另一个指针的指针。第二个指针指向一个指针表,表中的指针指向接口成员函数。该指针表称为 VTBL。将指针指向对象后,就可以通过调用接口中的成员函数与该对象通信。如何将指针指向第一个对象呢?可以调用一个

3、返回指向对象指针的 COM 函数如:CoCreateInstace()。COM 对象都提供一个叫 IUnknown 的接口,该接口包含方法 AddRef()、Release()和QueryInterface()。每个接口都是从 IUnknown 接口派生出来的。前两个方法操纵一个控制对象使用期限的内部引用计数。当对象第一次被创建时,创建者必须调用该对象的AddRef(),将计数加 1。每当其他的用户将一个指针指向该对象时,必须再次调用该对象的 AddRef()方法。当用户不再使用对象时,它调用对象的 Release()方法,将引用计数减1。当最后一个用户调用对象的 Release()方法后,计

4、数值变为 0,导致对象释放自己。下面是 AddRef()和 Release()方法的简单实现:ULONG IUnknown:AddRef(void)m_RefCount+;return m_RefCount;ULONG IUnknown:Release(void)m_RefCount-;if(m_RefCount=0) delete this;return 0;return m_RefCount;由于每一个对象都支持 IUnknown 接口,因此可以通过 QueryInterface()来询问对象是否支持您感兴趣的其它接口。接口通过接口 ID 来标识。HRESULT IUnknown:Quer

5、yInterface(REFIID riid,LPVOID FAR *ppv)if(riid=IID_IUnknown|riid=IID_IDropTarget)*ppv=(LPVOID)this;AddRef();Return S_OK;else *ppv=NULL;return E_NOINTERFACE;用于唯一地区分 COM 中条目的标识符是一个被称为 GUID(全局唯一标识符)或UUID(通用唯一标识符)。Typedef struct_GUIDunsigned long Data1;unsigned short Data2;unsigned short Data3;unsigned

6、char Data8;GUID;GUID 的取值范围非常大,16 个字节可能形成的不同组合为 3.41038。在 COM 中传输格式化数据的工作是通过数据对象处理的,数据对象是支持 IDataObject接口的对象。IDataObject 接口支持以下方法:IDataObject:GetData IDataObject:GetDataHere IDataObject:QueryGetDataIDataObject:GetCanonicalFormatEtc IDataObject:SetData IDataObject:EnumFormatEtcIDataObject:DAdviseIData

7、Object:DUnadviseIDataObject:EnumDAdvise决定了设计方案以及接口中需要包括的方法和参数后,必须使用接口描述语言(IDL) 编写接口的抽象定义。编写好.IDL 文件后,使用 VC+和 PlatformSDK 自带得 MicrosoftIDL 编译器编译,并生成头文件、勇于构建调度借口调用的代理和占为程序的代码以及实现开发工具和调用接口所必需的类型库。自动化,通过它 COM 对象可以将其功能提供给解释型客户(如脚本编写语言)而不是编译型客户使用。在开发阶段,当 COM 接口客户被编译时,编译器读取源代码,通过查阅头文件或类型库中的接口定义将方法名称解析为 VTB

8、L 条目,并生成目标代码,以便将必须的参数压入堆栈并跳到接口 VTBL 中相应条目保存的地址。编译过程可能需要很长时间,但编译后运行二进制代码的速度相对较快。而解释型客户在真正执行之前,不会将源代码解析为机器代码。自动化对象通过一个叫做 IDispatch 的标准接口暴露其所有的功能,而不是将每项功能作为自定义接口的 VTBL 中的条目来暴露。对对象的任何内部方法的调用都是通过该接口进行处理的。IDispatch 接口的方法包括:IDispatch:InvokeIDispatch:GetIDsOfNamesIDispatch:GetTypeInfoIDispatch:GetTypeInfoCo

9、unt当客户想调用自动化对象的内部方法时,它调用对象的 IDispatch:Invoke()。客户可使用 IDispatch:GetIDsOfNames 获得想要做事情的 ID。类型库是对象厂商提供的静态数据结构的集合,通过 ItypeLib 接口进行访问,包含关于单个对象、接口或类的信息。类型库可以包含描述下述内容的信息:服务器支持的对象类型 每个对象方法及其参数和类型 每个对象属性及其类型 枚举常量值 到在线文档中特定条目的引用COM Language RequirementsTheonly language requirement for COM is that code is gene

10、rated in a language thatcan create structures of pointers and, either explicitly or implicitly, callfunctions through pointers. Object-oriented languages such as C+ andSmalltalk? provide programming mechanisms that simplify the implementation ofCOM objects, but languages such as C, Pascal, Ada, Java

11、, and even BASICprogramming environments can create and use COM objects.以上摘自 MSDN,重要的是 C, Pascal, Ada, Java,and even BASIC 都可以用来编写COM。以上初步介绍了关于 COM 的一些东西,不多也很浅,理解以上的部分就够花费很长一段时间的了,如果真地对 COM 感兴趣的话,最好有一定的基础,包括:数据结构,面向对象的程序设计,Windows 编程等,不过也不一定都学,只是这些会对你学习 COM 并在短时间内掌握并深入理解 COM 会有相当的好处。COM 学习笔记(二)CoCre

12、ateInstance 具体内部实现cpp view plaincopy1. CoCreateInstance(.) 2. 3. /. 4. IClassFactory *pClassFactory=NULL; 5. CoGetClassObject(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void *) 6. pClassFactory-CreateInstance(NULL, IID_IUnknown, (void*) 7. pClassFactory-Release(); 8. /. 9. 这段话的意思就

13、是先得到类厂对象,再通过类厂创建组件从而得到 IUnknown 指针。继续深入一步,看看 CoGetClassObject 的内部伪码: cpp view plaincopy1. CoGetClassObject(.) 2. 3. /通过查注册表 CLSID_Object,得知组件 DLL 的位置、文件名 4. /装入 DLL 库 5. /使用函数 GetProcAddress(.)得到 DLL 库中函数 DllGetClassObject 的函数指针。6. /调用 DllGetClassObject 7. 8. /DllGetClassObject 是干什么的,它是用来获得类厂对象的。只有先

14、得到类厂才能去创建组件. 9. /下面是 DllGetClassObject 的伪码: 10. DllGetClassObject(.) 11. 12. /. 13. CFactory* pFactory= new CFactory; /类厂对象 14. pFactory-QueryInterface(IID_IClassFactory, (void*) 15. /查询 IClassFactory 指针 16. pFactory-Release(); 17. /. 18. 19. /CoGetClassObject 的流程已经到此为止,现在返回 CoCreateInstance,看看Creat

15、eInstance 的伪码: 20. CFactory:CreateInstance(.) 21. 22. /. 23. CObject *pObject = new CObject; /组件对象 24. pObject-QueryInterface(IID_IUnknown, (void*) 25. pObject-Release(); 26. /. 27. 这部分我们将构造一个创建 COM 组件的最小框架结构,然后看一看其内部处理流程是怎样的cpp view plaincopy1. IUnknown *pUnk=NULL; 2. IObject *pObject=NULL; 3. CoInitialize(NULL); 4. CoCreateInstance(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IUnknown, (void*) 5. pUnk-QueryInterface(IID_IOjbect, (void*) 6. pUnk-Release(); 7. pObject-Func(); 8.

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 解决方案

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号