现在的位置: 首页 > 综合 > 正文

COM学习笔记

2013年11月03日 ⁄ 综合 ⁄ 共 31563字 ⁄ 字号 评论关闭
 

COM 学习笔记

康  林 2004年11月

关键词:组件、接口、动态链接库、注册表、CLSID、GUID、IID、UUID

  1. 概念:

    1. 类型库:

    2. 组件:是一个接口的集合。

    3. 接口:是一个包含一个函数接针数组的内存结构。每一个数组元素包含的是一个由组件所实现的函数的地址。

      组件是接口的集合,接口是函数的集合。

  2. QueryInterface 的实现规则:

    1. QueryInterface 返回的总是同一个 IUnknown 指针。

    2. 若客户曾经获得过某个接口,那么它将总能获取此接口。

    3. 客户可以再次获得已经拥有的接口。

    4. 客户可以返回到起始接口。

    5. 若能够从某个接口获得某按按特定接口,那么可以从任意接口都将可以获得此接口。

  3. ProgID 与 CLSID的转换:

    1. ProgIDFromCLSID
      HRESULT CLSIDFromProgID(
        LPCOLESTR
      lpszProgID//Pointer to the ProgID
        LPCLSID pclsid         //Pointer to the CLSID
      );

    2. CLSIDFromProgID
      WINOLEAPI ProgIDFromCLSID(
        REFCLSID
      clsid//CLSID for which the ProgID is requested
        LPOLESTR * lplpszProgID
                         //Address of output variable that receives a
                         // pointer to the requested ProgID string
      );
       

  4. CLSID 与字符串的转换:

    1. CLSIDFromString
      HRESULT CLSIDFromString(
        LPOLESTR
      lpsz//Pointer to the string representation of the CLSID
        LPCLSID pclsid  //Pointer to the CLSID
      );

    2. StringFromCLSID
      WINOLEAPI StringFromCLSID(
        REFCLSID
      rclsid, //CLSID to be converted
        LPOLESTR * ppsz  //Address of output variable that receives a
                         // pointer to the resulting string
      );

    3. StringFromGUID2
      int StringFromGUID2(
        REFGUID
      rguid//Interface identifier to be converted
        LPOLESTR lpsz//Pointer to the resulting string on return
        int cchMax       //Character count of string at lpsz
      );
       

    4. StringFromIID
      WINOLEAPI StringFromIID(
        REFIID
      rclsid,     //Interface identifier to be converted
        LPOLESTR * lplpsz  //Address of output variable that receives a
                           // pointer to the resulting string
      );

    5. IIDFromString
      WINOLEAPI IIDFromString(
        LPOLESTR
      lpsz//Pointer to the string representation of the IID
        LPIID lpiid     //Pointer to the requested IID on return
      );

  5. 注册:

    1. 用程序注册:regsvr32.exe

    2. 调用动态函数库中的注册函数:DllRegisterServer

    3. 调用动态函数库中的反注册函数:DllUnregisterServer

  6. COM库函数:

    1. CoCreateInstance
        STDAPI CoCreateInstance(
           REFCLSID
      rclsid,     //Class identifier (CLSID) of the object
           LPUNKNOWN pUnkOuter, //Pointer to whether object is or isn't part
                                  // of an aggregate
           DWORD dwClsContext//Context for running executable code
           REFIID riid,         //Reference to the identifier of the interface
           LPVOID * ppv         //Address of output variable that receives
                                 // the interface pointer requested in riid
        );
      CoCreateInstance 实际上是调用
      CoGetClassObject 实现的。CoGetClassObject 将在注册表中查找指定的组件。找到之后,它将装载实现此组件的 DLL(用 CoLoadLibrary)。装载成功之后,它将调用在 DLL 服务器中的实现的 DllGetClassObject。此函数的作用是创建相应的类厂。另外 DllGetClassObject 还将查询 IClassFactory 接口,并将其返回给 CoCreateInstance。然后,CoCreatInstnce 将使用此接口来调用 IClassFactory::CreateInstance 函数。并查询指 CoCreateInstance 参数 riid 中指定的接口。在得到了此接口之后,CoCreateInstance 将释放相应的类厂并将此接口的指针返回给客户。然后客户就能使用此指针来调用组件中的某个方法了。

    2. CoGetClassObject
      STDAPI CoGetClassObject(
        REFCLSID
      rclsid//CLSID associated with the class object
        DWORD dwClsContext,
                          //Context for running executable code
        COSERVERINFO * pServerInfo,
                          //Pointer to machine on which the object is to
                          // be instantiated
        REFIID riid,      //Reference to the identifier of the interface
        LPVOID * ppv      //Address of output variable that receives the
                          // interface pointer requested in riid
      );

    3. CoFreeUnusedLibraries:释放不再使用的DLL
       
  7. 包容与聚合:
  8. 接口指针类(智能接口指针):

    1. ATL中有 CComPrt 和 CComQIprt(#include <ATLBASE.H>)

    2. MFC中有CIP(#include <afxcom_.h>)

    3. 使用接口类的成员函数,用 . 操作符。例如:
      CComQIPtr <InterfaceClass, &IID> spIF;
      spIF.Release(); //释放接口指针
    4. 释放接口指针类(智能接口指针):
      CComQIPtr <InterfaceClass, &IID> spIF;
      spIF = NULL; //释放接口指针
  9. C++包装类:(MFC OLE)

用嵌套类实现接口:

用 ATL 实现接口

  • 增加 ATL 对象类
    1. 操作步骤

    2. 增加的内容

     

  • 添加接口函数
    1. 操作步骤