COM基础

曾经看过潘老师的<<COM原理与应用>>的前三章,有些时间没怎么往下看了,趁这个周末休息正好把以前看过的三章重温一下,总结一下,然后继续往下学习

一.COM组件的实现

       COM组件分进程内组件和进程外组件

       进程内容组件主要是由DLL来实现,客户程序和组件程序运行在同一个进程地址空间。

       进程外组件文件格式为exe,运行在和客户程序不同的进程空间甚至不在同一台机器上。

二.GUID,CLSID,IID

       GUID:128位的全局唯一标示符,这是一个随机数,发生相重的几率非常小。

       CLSID:用来标示COM对象(COM类)的GUID

       IID:用来标示接口的GUID

三.COM组件的语言实现和内存模型

       用C++来实现COM组件目前是最合适的,因为C++的多态性,虚函数可以很好的用来实现COM的接口

       接口是一组函数的集合,而且是函数的申明的集合,没有包含实现。

       对于C++来说,用代码实现这样的接口也就是定义一个类,包含这些函数的申明(需要申明为虚函数)即可。

       对于COM组件模块来说,一个COM组件模块可以实现一个或者多个接口,对于C++来说,也就是编一些一个类集成并且实现他所IMPLEMENT的接口类的所有函数即可(其实也未必,如果你不在代码里调用这些未提供函数体实现的函数也是没由问题的)。

       如果一个COM组件实现多个接口,在C++的继承模式上不能采用虚拟继承来继承着多个接口类。 

       内存结构上来说COM组件类的对象中,存放着每一个实现的接口类的虚函数表,用于调到对应接口中的函数,并且可以用强制类型转换来返回接口指针,这个接口指针中至少包含了用来调用接口中申明的哪些函数的虚函数表。

       客户程序拿到了接口指针也就相当于可以调用包含这个接口指针的COM对象的其他接口了(通过查询接口)。

四.IUnKnown接口

       这个接口是每一个接口类的父类,提供用于管理内存,查询其他接口的函数

       1.AddRef       --增加对象的引用计数

       2.Release      --减少对应的引用计数

       3.QueryInterface    --通过IID返回对象的其他接口指针

       这三个函数式每个COM组件类必须实现的三个接口函数。

五.注册

       COM组件的注册使用WINDOWS的REGSVR32.exe提供注册的,该exe会调用COM组件中的DllRegisterServer和DllUnRegisterServer函数进行注册和反注册。

       如果是进程外组件,那么COM要求该exe支持运行参数/RegServer和/UnregServer并且对这两个参数做出处理。

六.类厂

       对于COM组件类,其创建是由COM库调用组件模块dll中的类厂对象生产组件类对象的。每个组件类都有一个对应的类厂类,类厂类实现了IClassFactory接口,这个接口作重要的函数就是CreateInstance函数,用于创建组件类对象,并且返回接口指针。

       由于类厂实现了IClassFactory接口,因此,类厂也是一个COM组件类,他的创建时有组件模块dll中的DllGetClassObject函数实现的,其中参数中的IID一般情况下是IClassFactory接口的IID,除非我们的类厂类实现了更多的接口(比如用户安全验证等)。

七.COM库

      在COM库中,有三个API函数用于对象的创建

      1.CoGetClassObject

      该函数调用com组件dll中的DllGetClassObject函数创建类厂对象,并且返回类厂接口指针(IClassFactory)

      2.CoCreateInstance

      该函数内部实际上先调用CoGetClassObject函数创建类厂对象,然后根据参数中的IID使用类厂对象的CreateInstance函数创建出组件对象,并且返回IID对应的接口指针,这些操作都是在组件内部和COM库之间进行的,客户程序相当于直接绕开类厂对象创建COM对象了。

      3.CoCreateInstanceEx

      该函数用于创建远程机器上的COM对象,暂时还未完全看懂。

       COM库的初始化:使用CoInitialize函数进行COM库的初始化。

       客户程序初始化COM库以后,就可以使用COM库提供的各种服务,在程序退出前,要调用CoUninitialize函数释放CIOM库管理的资源。

 

       进程内COM组件的卸载

       当客户程序退出前,要卸载COM对象,这是,COM库会调用组件模块dll的DllCanUnloadNow函数,该函数判断

       这个函数的调用由客户程序来进行,因为只有客户程序知道是否还需要使用该COM对象,如果不需要的话,调用COM库的CoFreeUnusedLibraries函数进行卸载。

 

八.COM库加载COM组件的流程

        目前只看懂了进程内组件的加载流程,如下:

        1.客户程序初始化COM库(CoInitialize)

        2.调用COM库的CoCreateInstance函数创建COM组件对象,返回接口指针(这一步COM库可能会LoadLibrary加载进程内组件的dll)

        3.使用接口指针完成操作

        4.客户程序调用COM库的CoFreeUnusedLibraries(COM库会调用组件dll的DllCanUnloadNow,如果返回true,则COM库使用FreeLibrary释放组件dll,并且返回true

)

        5.客户程序调用COM库的CoInitialize释放COM库资源。

 

九.HRESULT

       COM库的对象创建函数返回值很多都是这个类型的,他是一个32位整数,而不是一个资源的句柄,其31位和30位两位的值反应了函数调用的基本结果

       00  标示调用成功

       01  包含了一些信息

       10  警告

       11  错误

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值