• COM技术内幕第六章笔记HRESULT、GUID、注册表及其他


    HRESULT

    COM组件常使用HERESULT来向用户报告接口函数执行的情况。

    它是一个结构固定的32位值,分成三部分。


    最高位表示函数调用是否成功。低16位包含函数返回值。

    常用的HRESULT值

    S_OK                        函数成功。某些情况下表示函数返回了一个布尔true。S_OK定义为0。
    NOERROR                同上。
    S_FALSE                  函数成功并返回一个布尔false。S_FALSE被定义为1.
    E_UNEXPECTED      无法预知的失败。
    E_NOIMPLE              成员函数未被实现。
    E_NOINTERFACE     组件不支持请求的接口。由QueryInterface函数返回。
    E_OUTOFMEMORY 组件无法分配所需内存。
    E_FAIL                      没有指定的失败。

    HRESULT值中16-30位包含的设备代码,标识的是返回代码的操作系统部分。windows中设备代码如下

    FACILITY_WINDOWS          8
    FACILITY_STORAGE          3
    FACILITY_SSPI                    9
    FACILITY_RPC                  1
    FACILITY_WIN32                7
    FACILITY_CONTROL          10
    FACILITY_NULL                  0
    FACILITY_ITF                       4
    FACILITY_DISPATCH           2
    FACILITY_CERT                11

    WINERROR.H中包含当前系统产生的所有COM状态代码。大多数该类代码是十六进制形式。

    HRESULT使用

    因为HRESULT包含多个成功代码及多个失败代码,因此简单的比较不能用来判断成功与失败。

    而必须使用宏SUCCEEDEDFAILED

    GUID

    GUID,Globally Unique Identifier,全局唯一标识符。IID是一个128比特即16字节的GUID结构。

    MSVC++有两个建立GUID的程序,一个UUIDGEN.EXE,命令行方式的。一个GUIDGEN.exe,vc++的对话框应用。

    GUID在时间和空间上都是唯一的。生成它,需要一个48位的唯一值,也就是网卡地址,再加一个60位的间戳。

    GUID的声明和定义

    一种方法,分开定义

    .h中

    extern "C" const IID IID_IX;

    .cpp中

    extern "C" const IID IID_IX = {********值******};

    另一种,使用宏

    细节没太看懂。

    由于GUID值占用了16个字节,因此一般不使用值传递。QueryInterface第一个参数就是引用参数。

    注册表

    CLSID

    COM库函数CoCreateInstance用来创建组件,以组件的CLSID为参数。

    组件可以用CLSID作为索引在Windows注册表中发布包含它们的DLL文件名称。

    CoCreateInstance就是用CLSID作为关键字在注册表中查找需要的文件名称。

    COM只使用了注册表的一个分支HKEY_CLASS_ROOT。

    在此之下,可以看到CLSID关键字,CLSID之下列出了系统中安装的所有组件的CLSID。

    形如{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX},不易辨认,因此它的缺省值都是有意义的,用来表明组件。

    对每一个CLSID关键字,InprocServer32关键字的缺省值是组件所在的DLL文件名称。inprocServer32这个名称也就说明了问题。

    其他

    在HKEY_CLASS_ROOT之下,

    首先列出了应用程序所注册的文件扩展名。

    在扩展名之后是应用程序的名称,也就是程序员定义的标识符,即ProgID。

    ProgID的格式一般遵循:<program>.<component>.<version>

    ProgID也主要是用来获取对应的CLSID。COM库函数提供了CLSIDFromProgIDProgIDFromCLSID

    如何自注册

    在DLL中一定要输出如下两个函数:

    HRESTUL __stdcall DllRegisterServer();

    HRESTUL __stdcall DllUnregisterServer();

    所有的win32 API都遵循__stdcall限定符。

    DllRegisterServer和DllUnregisterServer的实现需要包含源文件winreg.h或windows.h,并将其同ADVAPI32.lib一块链接。

    实现细节暂且不表。

    组件类别

    为了方便客户调用,根据组件实现的接口的功能大致分类,为它们分配GUID,也就是CATID。

    对一个组件来说,要实现了该类组件类别的所有接口,才能被注册为该CATID的一个成员。

    组件类别可以由Windows系统附带的一个 Component Category Manager来完成对注册表的处理。它实现了两个主要的COM接口:ICatRegisterICatInformation

    COM库函数

    通过OLE32.DLL,COM定义了一个函数库用来实现COM组件都需要完成的程序化操作。包括

    COM的初始化,OleInitialize
    内存管理,IMalloc
    将字符串转化成GUID,StringFromGUID2

  • 相关阅读:
    多种语言求n的阶乘
    (转)Bullet 物理引擎 简析[1]
    (转)Bullet 引擎 详解 DBVT 分析
    (转载)C Runtime Library(MSVCRT)来历
    (转)角色蒙皮
    计算两向量的旋转角(转)
    lua中文教程(第二章 类型和值)
    lua中文教程(第一章 起点)
    (转)Bullet 引擎 详解 碰撞事件 回调函数
    (转)Bullet 3D 物理引擎 简析(2)
  • 原文地址:https://www.cnblogs.com/mumuliang/p/1873486.html
Copyright © 2020-2023  润新知