IDispatchEx Interface

得从IDispatchEx接口开始说起,它是IDispatch的扩展接口。

IDispatch最早是给VB用的,它假设标物(object)是静态的,也就是标物在运行时是不会改变的,编译时所获取的类型信息就是不变的。但是这个假设在脚本语言VBScript以及JScript之上不太合理,于是乎IDispatchEx应用而生。

Ex版实现了IDispatch的全部服务,并提供了一些扩展:

  • GetDispID 搭配fdexNameEnsure 可以给标物添加新成员
  • DeleteMemberByName 删除成员
  • fdexNameCaseSensitive 或fdexNameCaseInsensitive可做大小写区分的联调(dispatch)
  • fdexNameImplicit,隐式查找
  • InvokeEx
  • GetNameSpaceParent支持命名空间
  • 成员及其参数的DISPIDs 必须恒定不变
  • DISPID 不可以在不同名字的成员间复用
  • DISPID 必须对GetNextDispID有效
  • DISPID 必须被IDispatch和IDispatchEx 良好接受

Wikipedia IDispatch

对IDispatch的介绍还是比较简单的,主要是下面这句话

IDispatch is the interface that exposes the OLE Automation protocol.

Win32 Automation Creating the IDispatch Interface

IDispatch上的方法们

  • GetTypeInfoCount,对于支持IDispatch的标物,此处必须返回1
  • GetTypeInfo, 获取接口的TypeInfo
    • count只能返回1,是不是意味着此处只能返回一个接口的信息
    • 多于一个接口的话需要通过继承来搞定
    • 可能是因为VB不支持多继承?
  • GetIDsOfNames
    • 完成名字到ID的映射
  • Invoke
    • 呼调标物的方法

实现IDispatch的几种方式

  • 通过 DispInvoke、 DispGetIDsOfNames或者通过ITypeInfo::Invoke、 ITypeInfo::GetIDsOfNames来实现,反正都需要TypeInfo
  • 调用CreateStdDispatch 直接创建一个接口
  • 自行实现,但是Ivoke实现起来还是相当麻烦的

Win32 Automation IDispatch interface (oaidl.h)

比较复杂的是其中的IDispatch::Invoke方法。

Win32 Automation Type Description Interfaces

TypeInfo将虚函数表以元数据的方式体现出来了。

Win32 Automation ITypeLib interface (oaidl.h)

用于查看标类料库(type library)信息。

可能最重要的是ITypeLib::GetTypeInfoOfGuid

Win32 Automation ITypeInfo interface (oaidl.h)

比较重要的是ITypeInfo::Invoke method (oaidl.h)吧。

C++/WinRT Author COM components with C++/WinRT

Windows Runtime刻意不支持接口派生,具体原因不详。

小结

几点感觉

  • Windows这么多年只是在COM的元数据格式上做出了改进,从以前的typelibrary变为现在的windows metadata。
  • OLE Automation其实是根据类型来各种互知互联的。

其他

主题链接

(完)