lgxqf  

 

COM 原理与应用

 

第一章 概述

GUID-->Com 接口--->函数(提供服务)

 

COM对象的进程模型:3

         进程内服务程序

         本地服务程序

         远程服务程序

 

第二章 COM对象和接口

         _cdecl有些语言不支持,所以COM对象的接口函数都要用_stdcall,只有确认客户程序也是C++时才可用_cdecl

         COM的位置对客户是透明的,因为客户并不直接去访问COM组件,而是通过COM组件的CLSID来创建和初始化COM对象

         COM对象的可重用性:包含和聚合

         COM要求使用Unicode字符,所以如果COM内部使用了ANSI字符 则必须把ANSI字符转换为Unicode 如: _com_util::ConvertBSTRToString

         如果客户程序要使用COM对象的某个接口,它必须知道接口的IDD和接口所能提供的方法。

         VC提供的MIDL工具,可以IDL接口描述文件编译成C/C++的接口头文件。

         一个COM组件可以实现多个COM对象。一个COM对象可以支持多个COM接口。

         COM接口规则:不管我们从哪个接口出发总可以达到任何一个接口,而且我们总可以回到最初的那个接口

 

第三章 COM的实现

         进程内组件(进程内服务程序)通常是DLL

                   效率高 但不安全 DLL若引发异常 则客户程序会异常退出

                   动态库调用:LoadLibrary-->GetProcAddress-->FreeLibrary

                   DLL程序不仅可以引出函数,还可以引出全局变量

         进程外组件(进程外服务程序)通常是EXE可执行程序。效率低 但安全   DLL若引发异常 客户程序不受影响

                   LPC 同一台机器上的不同进程

                   RPC 不同机器上的不同进程

                   进程外组件的组成:组件外服务程序、代理DLL、存根DLL

                   COM库是通过系统注册表所提供的信息进行组件创建工作的。

         COM与注册表

                   每个COM组件在注册表中都有相应的值,具体位置在 HKEY_CLASSES_ROOT"CLSID

                   如果是进程内组件 CLSID下子键包含了InprocServer32子键, 缺省值为组件程序的全路径文件名

                   如果是进程外组件 CLSID下子键包含了LocalServer32子键, 缺省值为组件程序的全路径文件名

                   Windows系统中除了可以用CLSI标识一个COM对象外,同时可以用字符串对组件对象命名,利用名字化的对象来查找对象.这个名字信息            

                   称为ProgID(Program Identifier,程序标识符), 被直接放在注册表的的HKEY_CLASSES_ROOT

                   ProgIDCLSID之间的转换函数是 ProgIDFromCLSID CLSIDFromProgID

                   COM提供了在注册表中对COM组件进行分类的机制。实现相同接口的COM组件被分到同一个类中。每个类都有个CATID.可以用VColeviewer查看

                   当前机器上的所有         

                   COM组件的类别信息。

         COM组件的注册

                   进程内组件(DLL) 必须实现两个函数 DllRegisiterServer DllUnregisiterServer

                            命令:RegSvr32 Dll文件名     会调用DLL中的DllRegisiterServer 来完成组件的注册

                            命令:RegSvr32 /u Dll文件名 会调用DLL中的DllUnregisiterServer 来完成组件的注销

                   进程组件(EXE)   Com规定EXE组件必须支持两个参数/RegServer   /UnregServer 通过指定不同的参数完自成组件的注册和注销

 

         类厂和DllGetObjectClass函数

                 COM函数库在创建COM对象时要求调用COM对象的一个入口函数DllGetObjectClass.

                 COM库通过类厂来创建COM对象。对应每一个COM,有一个类厂专门用于该类的对象创建操作。

类厂本身是个COM对象,它有特殊的接口。                

class IClassFactory: public IUnknown

{

    public:

        //COM对象创建完毕后 根据IID返回相应的接口

        virtual  HRESULT _stdcall   CreateInstance(IUknown * pUnknowOuter, const IID &iid, void **ppv) = 0;

        //控制组件的生命周期

        virtual  HRESULT _stdcall   LockServer(BOOL bLock) = 0;

}

                 COM库用DllGetObjectClass创建类厂对象 然后调用类厂的CreateInstance创建COM对象

           COM库与类厂的交互:

                            COM库中有三个API函数可用于对象的创建,它们分别是CoGetClassObjectCoCreateInstanceCoCreateInstanceEx

                            客户程序调用其中之一完成对象的创建,并返回对象的初始接口指针。

                           

联系与区别:

It is convenient to use CoCreateInstance when you need to create only a single instance of an object on the local machine. If you are creating an instance on remote machine, call CoCreateInstanceEx. When you are creating multiple instances, it is more efficient to obtain a pointer to the class object's IClassFactory interface and use its methods as needed. In the latter case, you should use the CoGetClassObject function.

 

                            CoGetClassObject      它会调用COM库中的DllGetObjectClass 获取类厂对象,(根据clsid所指定的类厂 然后返回类厂对象。)

                            CoCreateInstance      先调用CoGetClassObject返回类厂的对象,然后利用类厂对象的CreateInstance函数创建COM对象。

         COM

                            以上的几个函数都是COM库提供的函数,要使用COM库提供的函数我们必须先初始化COM

                            CoInitialize初始化COM             CoUninitialize释放COM库所维护的资源  

posted on 2008-11-20 22:41  Justin_Ma  阅读(435)  评论(0)    收藏  举报