zoukankan      html  css  js  c++  java
  • COM本质论学习笔记(一)IDL

    IDL是Interface Definition Language的所写,翻译为接口定义语言

    1.该语言规定,必须显式的为每个接口函数指定参数的目的,例如
    HRESULT foo([in]long* Input, [out]long* Output, [in, out]long* InAndOut);

    2.通常,函数的返回值为HRESULT,表示执行的状况,以便被其他语言所捕获,例如Visual Basic等。HRESULT大体分为三个部分:

    31|30 29|28 ... 16|15 ...0
    成 | 保留 |   操作码 | 信息码





    第31位如果是0那么代表成功,否则代表失败,这也是Win32 SDK的SUCCESSED宏判断的依据:
    #define SUCCESSED(hr) (long(hr) >= 0)
    #define FAILD(hr) (long(hr) < 0)

    3.该返回值只提供了函数的执行情况,函数可以另外提供返回值:
    HRESULT foo([in]long* Input, [out]long* Output, [out, retval]long* InAndOut);
    该函数在VB里看起来应该是这样的(凭记忆,未验证):
    Public Declare Function foo(ByVal Input as Integer, ByRef Output as Integer) as Integer
    如果在VB中调用该函数失败了,那么不是通过返回值把错误码返回,而是VB的解释器触发一个异常,你需要在VB里用On Error xxxx来进行错误处理。

    4.声明一个接口。接口的声明是如下形式滴~
    [object, uuid(00000000-0000-0000-0000-000000000000)]
    interface IMyInterface : IBaseInterface
    {
        enum MyEnum
        {
            ME_aa,
            ME_bb,
        }
        typedef struct _ASTRUCT
        {
            MyEnum me;
            long val;
        }
        HRESULT foo1([in]LONG* Input, [out, retval]RetVal);
    }

    []中的部分是接口属性,其中object代表这是一个com接口,后面的部分是全局唯一标识符(GUID),当用在com接口时,也叫做接口标识符(IID)。

    接下来IMyInterface是接口名,IBaseInterface是基接口名
    {}中则是接口体。

    5.细说GUID\IID\CLSID
    GUID是个128位的大数,所以COM用一个结构体来表示GUID
    typedef struct _GUID
    {
        DWORD  Data1;
        WORD    Data2;
        WORD    Data3;
        BYTE      Data4[8];
    }GUID;
    你看 (4+2+2+8)*8=128.
    同时,还有如下定义:
    typedef GUID IID;
    typedef GUID CLSID;

    所以说,IID,CLSID和GUID都是一种东东。
    有时为了判断2个GUID是否相等,那么用引用就会很高效,所以还有如下宏定义,以及== 和 !=操作符:
    #define REFGUID   const GUID&
    #define REFIID      const IID&
    #define REFCLSID  const CLSID&

    这个GUID/IID通常用VCSDK附带的GUIDGEN.EXE来生成,理论上不会重复~

    6.结构体与联合体
    在IDL中也可以声明结构体和联合体
    typedef struct _TestStruct
    {
        long a;
        short b;
    }TESTSTRUCT;

    struct TESTSTRUCT2
    {
        long a;
        short b;
    };

    union VALUE
    {
        [case(1)]long a;
        [case(2)]short b;
    };

    也可以在结构体或者函数中使用联合:
    struct TESTSTRUCT3
    {
        short t;
        [switch_is(t)]union VALUE
        {
            [case(1)]long a;
            [case(2)]short b;
        };
    };

    HRESULT foo1([in, switch_is(t)]union VALUE* pu, [in]short t);

    7.属性
    给接口添加属性,可以使用户感觉更良好:
    [object, uuid(...)]
    interface IPropertyInterface : IUnknown
    {
        // 只读
        [propget] HRESULT Age([out, retval]long* RetVal);

        // 读写
        [propput] HRESULT ID([in]long id);
        [propget] HRESULT ID([out, retval]long* id);
    }
    实现这样的接口也比较容易,只需要在C++类对应的方法前加get_或者put_即可
    class CPropertyInterface : public IPropertyInterface
    {
        public:
        ....
        HRESULT get_Age(long* RetVal);
        HRESULT get_ID(long* RetVal);
        HRESULT put_ID(long id);
    }

  • 相关阅读:
    【Java EE 学习 36】【struts2】【struts2系统验证】【struts2 ognl值栈】【struts2 ongl标签】【struts2 UI标签】【struts2模型驱动和令牌机制】
    【Java EE 学习 35 下】【struts2】【struts2文件上传】【struts2自定义拦截器】【struts2手动验证】
    【Java EE 学习 35 上】【strus2】【类型转换器】【struts2和Servlet API解耦】【国际化问题】【资源文件乱码问题已经解决】
    【Java EE 学习 34】【struts2学习第一天】
    【JavaScript中的正则表达式】
    【Java EE 学习 33 下】【validate表单验证插件】
    【Java EE 学习 33 上】【JQuery样式操作】【JQuery中的Ajax操作】【JQuery中的XML操作】
    【Java EE 学习 32 下】【JQuery】【JQuey中的DOM操作】
    【Java EE 学习 32 上】【JQuery】【选择器】
    【Java EE 学习 31】【JavaScript基础增强】【Ajax基础】【Json基础】
  • 原文地址:https://www.cnblogs.com/yoran/p/1099601.html
Copyright © 2011-2022 走看看