IUnknow IDispatch IInspectable QueryInterface
IUnknow接口是个伟大的创造!
IUnknow的AddRef和Release实现对象的引用计数管理, 引用计数用来管理对象的生存周期。
通过引用计数一来可以很方便的共享对象, 另外也能确保对象被正确释放(确保对象的new和delete在同一模块中)。
QueryInterface实现接口查询, 通过这种方式可以很方便的对现有组件进行升级, 只要接口不改 ,可以随意修改内部实现而不用客户程序重新编译。
另外也可以直接增加新接口, 只要在QueryInterface内增加并可以查询到该新接口, 我们就可以调用该新接口。
我们可以看到QueryInterface让C++这种静态语言有了某些动态语言的特性, 在C# 中我们可以通过反射查询到某个类的成员函数和成员变量, Objective-C中我们也可以根据函数名动态调用某个函数, 在脚本语言中,我们可以在运行时动态查询和修改某个类的信息。通过COM的QueryInterface, 我们可以动态查询某个组件类实现哪些接口(函数)。当然他们之间有本质的区别, 动态语言运行时内存中保存有类信息, 而C++的QueryInterface通过switch case, 返回的是存有虚表指针的对象指针。
最后再简单谈下IUnknown的升级版IDispatch和IInspectable。

先看IDispatch:

    IDispatch : public IUnknown
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount( 
            /* [out] */ __RPC__out UINT *pctinfo) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE GetTypeInfo( 
            /* [in] */ UINT iTInfo,
            /* [in] */ LCID lcid,
            /* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames( 
            /* [in] */ __RPC__in REFIID riid,
            /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,
            /* [range][in] */ UINT cNames,
            /* [in] */ LCID lcid,
            /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId) = 0;
        
        virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke( 
            /* [in] */ DISPID dispIdMember,
            /* [in] */ REFIID riid,
            /* [in] */ LCID lcid,
            /* [in] */ WORD wFlags,
            /* [out][in] */ DISPPARAMS *pDispParams,
            /* [out] */ VARIANT *pVarResult,
            /* [out] */ EXCEPINFO *pExcepInfo,
            /* [out] */ UINT *puArgErr) = 0;
        
    };
IDispatch继承于IUnknown, 通过IDispatch, 我们可以实现脚本语言对COM组件的调用,我们可以通过GetTypeInfo获取对象的类型信息, 通过GetIDsOfNames函数以字符串的方式获取函数的DISPID, 通过Invoke动态调用某个函数。IE的DOM对象与JS的交互全部是通过IDispatch(Ex)接口实现的。当然,除非你的组件要与脚本语言交互, 否者一般不用实现该接口。
再看IInspectable:

    IInspectable : public IUnknown
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE GetIids( 
            /* [out] */ __RPC__out ULONG *iidCount,
            /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID **iids) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE GetRuntimeClassName( 
            /* [out] */ __RPC__deref_out_opt HSTRING *className) = 0;
        
        virtual HRESULT STDMETHODCALLTYPE GetTrustLevel( 
            /* [out] */ __RPC__out TrustLevel *trustLevel) = 0;
        
    };

IInspectable也继承于IUnknown, 它是WinRT所有对象的基接口, 所以WinRT还是基于COM技术。
其中GetTrustLevel返回信任等级, GetRuntimeClassName返回类名, 而GetIids返回当前类对象实现了哪些接口(所有接口的iid), 得到接口的iid后, 我们就可以通过QueryInterface查询我们需要的接口了, 得到接口指针就可以调用内部函数了。
最后总结下,回答下文章开头的问题, 很多人说COM过时了, 也许”纯正的标准COM“确实是使用的人越来越少了, 但是COM的思想却一直在后续的软件开发中被使用和发扬, 可以说COM技术是微软技术框架的“根”(之一)。

posted on 2014-03-14 09:11 提里奥弗丁 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/Fordring/p/3599803.html

IUnknow IDispatch IInspectable QueryInterface相关推荐

  1. 以远程计算机上的用户身份访问Com+应用

    DELPHI程序员开发com+应用的速度是非常快的,其主要原因是其较好地封装了com+的window s底层功能,开发人员通过较为简单的类继承就避开了复杂的com+底层技术细节,使开发人员 将精力放在 ...

  2. 【摘自网上】Delphi TppReport

    在TppBDEPipeline的DataSource中关联数据源 TppReport中的DataPipeline中设置TppBDEPipeline TppViewer的Report中设置TppRepo ...

  3. Win32 .Net QA 200509

    CSDN 讨论总结系列: Jiangsheng的CSDN Digest (Dec 2005)(http://blog.csdn.net/jiangsheng/archive/2005/12/24/56 ...

  4. 在Qt中用QAxObject来操作Excel

    目录(?)[+] 下一篇: 用dumpcpp工具生成的excel.h/excel.cpp来操纵Excel 最近写程序中需要将数据输出保存到Excel文件中.翻看<C++ GUI Programm ...

  5. 通过QueryInterface接口查询和使用IDispatch 接口进行操作的对比。

    写一个提交网页表单的程序.比较了一下QueryInterface接口查询和使用IDispatch 接口进行操作 . 通过 QueryInterface 接口查询,然后再进行条件判断显然是比较烦琐的,但 ...

  6. COM 组件设计与应用(十一)—— IDispatch 及双接口的调用

    原文:http://www.vckbase.com/index.php/wv/1236 一.前言 前段时间,由于工作比较忙,没有能及时地写作.其间收到了很多网友的来信询问和鼓励,在此一并表示感谢.咳. ...

  7. JS和C#访问遇到QueryInterface调用出错

    在原来的WinForm里,我们只要在窗体类的头部添加属性[System.Runtime.InteropServices.ComVisibleAttribute(true)],然后 webBrowser ...

  8. CorelDRAWX4的C++插件开发(四十)纯C++插件开发(4)继承插件结构体IVGAppPlugin和自动化接口IDispatch

    因为在注册插件的时候,是要传一个名为IDispatch*这样子的一个参数,所以我们可以看到插件在注册的时候默认就是要求这是一个实现了自动化的接口(IDispatch,如下图所示,是后面将要展示的代码, ...

  9. IUnKNown接口——QueryInterface函数

    转自:IUnKNown接口--QueryInterface函数 客户同组件的交互都是通过一个接口完成的.在客户查询组件的其他接口时,也是通过接口完成的.这个接口就是IUnknown.它在UNKNWN. ...

最新文章

  1. SpringMVC 学习系列 (3) 之 URL请求到Action的映射规则
  2. python安装步骤3.7.2-python安装步骤_python 3.7.2安装教程
  3. 洛谷4400 BlueMary的旅行(分层图+最大流)
  4. OpenMP变量的私有与共享
  5. python权威指南 pdf_Ansible权威指南pdf txt mobi下载及读书笔记
  6. c 数组上限_高级I/O复用技术:Epoll的使用及一个完整的C实例含代码
  7. 数学建模教程:GSpan-频繁子图挖掘算法
  8. Android studio进行文件对比
  9. Mac笔记本安装maven
  10. javaee实训报告总结_javaee实习报告.doc
  11. 微信字体大小调整导致的H5页面错乱问题处理
  12. Relatively Prime Pairs
  13. PS中级应用系列-徐鹏-专题视频课程
  14. DP(最长上升子序列)——腾讯校招题:逛街
  15. 函数定义涉及的三要素C语言,(函数定义与三要素答案.doc
  16. Diffusion Models专栏文章汇总:入门与实战
  17. win10 右键卡顿问题
  18. Direct Shot Correspondence Matching
  19. 航空燃气涡轮发动机分类
  20. Qcom 8909 sbl1流程

热门文章

  1. .net trim 替换指定字符_CAD二次开发实例:批量文本查找替换
  2. 架构解密从分布式到微服务:微服务架构到底是什么?
  3. 无法启用Windows Hello-某些设置由您的组织管理
  4. 016.OpenStack及云计算(面试)常见问题
  5. 猫影视接口相关及短网址
  6. Java基础学习总结(148)——如何提高代码质量
  7. Windows学习总结(13)——各品牌电脑进入BIOS按键汇总
  8. PHP学习总结(6)——PHP入门篇之PHP语句结束符
  9. Maven学习总结(23)——Maven常用命令介绍
  10. 专访阿里云高级专家赵林:从0到1,中间件的研发运维之路