COM原理
+ -

COM简介

2022-02-07 142 0

COM是什么

COM是由Microsoft提出的组件标准,它不仅定义了组件程序之间进行交互的标准,并且也提供了组件程序运行所需的环境。在COM标准中,一个组件程序也被称为一个模块,它可以是一个动态链接库,被称为进程内组件;也可以是一个可执行程序(即EXE程序),被称作进程外组件

一个组件程序可包含一个或多个组件对象,因为COM是以对象为基本单元的模型,所以在程序与程序之间进行通信时,通信的双方应该是组件对象,也叫做COM对象,而组件程序(或称作COM程序)是提供COM对象的代码载体。COM对象不同于一般面向对象语言(如C++语言)中的对象概念,COM对象是建立在二进制可执行代码级的基础上,而C++等语言中的对象是建立在源代码级上,因此COM对象是语言无关的。这一特性使用不同编程语言开发的组件对象进行交互成为可能。

COM对象与接口

类似于C++中对象的概念,对象是某个类的一个实例;

  • 类则是一组相关的数据和功能组合在一起的一个定义。使用对象的应用(或另一个对象)称为客户,有时也称为对象的用户。
  • 接口是一组逻辑上相关的函数集合,其函数也被称为接口成员函数。按照习惯,接口名常是以I为前缀。COM对象通过接口成员函数为客户提供各种形式的服务。

在COM模型中,对象本身对客户来说是不可见的。客户请求服务时,只能通过接口进行。每个接口都由一个128位的全局唯一标识符来标识。客户通过GUID来获得接口指针,再通过接口指针,客户就可调用其成员函数。

与接口类似,每个组件也用一个128位GUID来标识,称为CLSID(类标识或类ID),用CLSID标识对象可保证(概率意义上)在全球范围内的唯一性。实际上,客户成功地创建对象后,它得到的是一个指向对象某个接口的指针,因为COM对象至少实现一个接口(没有接口的COM对象是没有意义的),所以客户就可调用该接口提供的所有服务。根据COM规范,一个COM对象如果实现了多个接口,则可从某个接口得到该对象的任意其它接口。从这个过程也可看出,客户与COM对象只通过接口打交道,对象对客户来说只是一组接口。

从技术上讲,接口是包含了一组函数的数据结构,通过这组数据结构,客户代码可调用组件对象的功能。接口定义了一组成员函数,这组成员函数是组件对象暴露出来的所有信息,客户程序利用这些函数获得组件对象的服务。

通常把接口函数表称为虚函数表(vtable),指向vtable的指针为pVtable。对一个接口来说,它的虚函数表是确定的,因此接口的成员函数个数不变,成员函数的先后顺序也不变;对每个成员函数来说,其参数和返回值也是确定的。在一个接口的定义中,所有这些信息都必须在二进制一级确定,不管什么语言,只要能支持这样的内存结构描述,就可使用接口。

每一个接口成员函数的第一个参数为指向对象实例的指针(=this),这是因为接口本身并不独立使用,它必须存在于某个COM对象上,因此该指针可提供对象实例的属性信息,在被调用时,接口可知道是对哪个COM对象在进行操作。

在接口成员函数中,字符串变量必须用Unicode字符指针,COM规范要求使用Unicode字符,且COM库提供的API函数也使用Unicode字符。所以,如果在组件程序内部使用了ANSI字符,就应进行两种字符的转换。当然,在既建立组件程序又建立客户程序的情况下,可使用自定义参数类型,只要它们与COM所能识别的参数类型兼容。VC++提供两种字符串的转换:

namespace _com_util {
    BSTR ConvertStringToBSTR(const char *pSrc)throw(_com_error);
    BSTR ConvertBSTRToString(BSTR pSrc)throw(_com_error);
}

BSTR是双字节串,是最常用的自动化数据类型

COM优点

用ATL写一个COM组件,在组件中实现了一个自定义接口(当然可把200个函数都加到这一个接口中,果真如此的话,恐怕就没有人使用这个组件了)。

一个组件既然可提供多个接口,那么在设计时,就应按函数功能进行分类,把不同功能分类的函数用多个接口表现出来。优点是:
1.一个接口中的函数个数有限、功能集中,便于学习使用;
2.容易维护和升级。

0 篇笔记 写笔记

IRP的完成IoCompleteRequest
每当一个IRP在下层设备层完成时,是需要调用IoCompleteRequest来实现IRP的完成,这个完成其实是实现对执行的IRP的善后操作,这个操作其实是一个宏,真实函数数是IofCompleteRequest。#define IoCompleteRequest IofCompleteReque......
IoCopyCurrentIrpStackLocationToNext和IoSkipCurrentIrpStackLocation操作的IO_STACK_LOCATION有什么区别
在Windows驱动中,传递IPR一般有两种操作:一种是调用IoSkipCurrentIrpStackLocation,表示跳过本层驱动的操作,直接转发至下层: IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(FDODeviceEx......
IRP完成APC执行函数IopCompleteRequest
IRP在完成时调用IoCompleteRequest,其最终会执行一个APC调用,该调用的函数名为IopCompleteRequest。其调用APC调用时的代码如下:KeInitializeApc(&Irp->Tail.Apc, &......
WDDM 显卡及显卡驱动的分类
随着显卡的技术的发展,对于三维图形处理的功能越来越强,所以直接导致的一个结果就是显卡的数学处理能力(浮点计算)的功能越来越强。所以对于一些需要进行大量数学计算的模块,将这些功能交由显卡来进行处理相比较CPU更能大幅度提高效率。如现在的人功智能AI,还有前几年火热的挖矿…这些都是需要复杂的数学计算......
PortClass中的COM
一般的Windows驱动我们采用的是WDM驱动架构,最近的Windows驱动架构WDF也是建立在WDM基础上的。这些基于WDM的一般设备驱动可以应付大部分的设备驱动,如串口,PCI,USB等通用设备驱动。但是微软的关于流的处理的一些服务及驱动采用的面向对象的设计方法,是基于COM进行开发的,典型的像......
IRP完成例程IoSetCompletionRoutine的设计和实现原理
在进行IRP下层传递时,通过上一节可知道,一种中使用IoCopyCurrentIrpStackLocationToNext,另一种是IoSkipCurrentIrpStackLocation。其中在使用IoCopyCurrentIrpStackLocationToNext表示的是对当前的IRP当留当......
COM的QueryInterface与NonDelegatingQueryInterface关系
COM类的实现如下:class CMyComponent : public CUnknown, public ISomeInterface{public: DECLARE_IUNKNOWN; STDMETHODIMP NonDelegatingQueryInterface(RE......
COM的QueryInterface与NonDelegatingQueryInterface的测试用例
COM中,函数的调用实际是汇编 call 函数地址.对于一个类里定义的函数实际是一个一个的地址偏移.如果地址偏移是一样而且参数个数与排列都一样,函数叫什么名字是没有关系的。这里关于这句话做一个测试用例,用于测试COMM的妙用:#include #include......
COM简介
COM是什么COM是由Microsoft提出的组件标准,它不仅定义了组件程序之间进行交互的标准,并且也提供了组件程序运行所需的环境。在COM标准中,一个组件程序也被称为一个模块,它可以是一个动态链接库,被称为进程内组件;也可以是一个可执行程序(即EXE程序),被称作进程外组件。一个组件程序可包含一......
COM的应用
当给组件增加函数时,无需修改已发表的接口,而是提供一个新的接口来完成功能扩展。组件A有2个自定义接口,组件B是A的升级,接口结构如下:假设设计了组件A,它有2个自定义接口。IMathe有Add方法完成整数加法,IStr有Cat方法完成字符串连接。升级组件A到B,欲增加一个Mul方法完成整数乘法。由于......
COM全局唯一标识符GUID
COM规范采用了128位全局唯一标识符GUID来标识对象和接口,这是一个随机数,并不需要专门机构进行分配和管理。因为GUID是个随机数,所以并不绝对保证唯一性,但发生标识符相重的可能性非常小。从理论上讲,如果一台机器每秒产生10000000个GUID,则可保证(概率意义上)的3240年不重复)。GU......
COM 接口描述语言IDL
COM规范在IDL接口描述语言(OSF的DCE规范)的基础上,通过扩展形成了COM接口的描述语言。接口描述语言提供了一种不依赖于任何语言的接口的描述方法,因此,可成为组件程序和客户程序之间的共同语言。COM规范使用的IDL不仅可用于定义COM接口,同时还定义了一些常用数据类型,也可描述自定义的数据......
COM进程模型及可用性特性
COM进程模型COM有两种进程模型:进程内对象和进程外对象。如果是进程内对象,则它在客户进程空间上运行;如果是进程外对象,则它运行在本机上的另一个进程空间或远程机上。进程内服务器:服务程序被加载到客户的进程空间,在Win32环境下,通常服务程序代码以动态连接库(DLL)的形式实现;本地服务器:服......
COM组件注册信息
根据COM规范,客户程序通过COM库完成COM对象的创建,COM库则通过注册表所提供的信息进行组件的创建。注册表中包含了所有COM组件的必要信息。组件程序和客户程序都可访问注册表。组件程序把它所实现的COM对象的信息及接口信息保存到注册表中,称之为组件的注册。COM组件在HKEY_CLASSES_......
COM 类厂和DllGetObjectClass函数
类厂是COM对象的生产基地,COM库通过类厂创建COM对象;对应每一个COM类,都有一个类厂,用于该COM类的对象创建操作。类厂本身也是一个COM对象,它支持一个特殊接口(IClassFactory):class IClassFactory:public IUnknown{ virtua......
作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!