第11章 调度接口与自动化

 
第11章 调度接口与自动化

1、自动化是建立在COM基础上的。

2、一个自动化服务器实际上就是一个实现了IDispatch接口的COM组件。

3、一个自动化控制器则是一个通过IDispatch接口同自动化服务器进行通信的COM客户。

自动化控制器不会直接调用自动化服务器实现的那些函数,而是通过IDispatch接口中的成员函数实现对服务器中函数的间接调用。

4、IDispatch 接口有4个函数,解释语言的执行器就通过这仅有的4个函数来执行组件所提供的功能。这4个函数功能如下: 

HRESULT GetTypeInfoCount(

    [out] UINT * pctinfo)

组件中提供几个类型库?当然一般都是一个啦。

但如果你在一个组件中实现了多个 IDispatch 接口,那就不一定啦(注1)

HRESULT GetTypeInfo(

[in] UINT iTInfo,

[in] LCID lcid,

[out] ITypeInfo ** ppTInfo)

调用者通过该函数取得他想要的类型库。

幸好,在 99% 的情况下,我们都不用关心这两个函数的实现,因为 MFC/ATL 都帮我们完成了默认的一个实现,如果是自己完成函数代码,甚至可以直接返回 E_NOTIMPL 表示没有实现。(注2)

HRESULT GetIDsOfNames(

[in] REFIID riid,

[in,size_is(cNames)] LPOLESTR * rgszNames,
    [in] UINT cNames,

[in] LCID lcid,

[out,size_is(cNames)] DISPID * rgDispId)

根据函数名称取得函数序号,为调用 Invoke() 做准备。

所谓函数序号,大家去观察双接口 IDL 文件和 MFC 的 ODL 文件,每一个函数和属性都会有 [id(序号)....] 这样的描述。

HRESULT Invoke(
    [in] DISPID dispIdMember,

    [in] REFIID riid,

    [in] LCID lcid,

    [in] WORD wFlags,

    [in,out] DISPPARAMS * pDispParams,

    [out] VARIANT * pVarResult,

    [out] EXCEPINFO * pExcepInfo,

    [out] UINT * puArgErr)

根据序号,执行函数。
使用 MFC/ATL 写的组件程序,我们也不必关心这个函数的实现。如果是自己写代码,则该函数类似如下实现:
switch(dispIdMember)
{

    case 1: .....; break;

    case 2: .....; break;

    ....

}

其实,就是根据序号进行分支调用啦。(注3)

 

 

5、双重接口:让实现IDispatch::Ivoke的COM组件继承IDispatch而不是IUnknown。它使得通过Invoke能够访问的函数也能够直接通过vtbl访问到(C++程序员使用vtbl)。所以叫双重接口。

 

6、双接口(dual) 结构示意图:

 

7、VARIANT:函数内部动态判断参数类型,实际上是不同类型值的一个大联合体union。

8、双接口有什么好处 

使用方式

因为

所以

脚本语言使用组件

解释器只认识 IDispatch 接口

可以调用,但执行效率最低

编译型语言使用组件

它认识 IDispatch 接口

可以调用,执行效率比较低

编译型语言使用组件

它装载类型库后,就认识了 Ixxx 接口

可以直接调用 Ixxx 函数,效率最高啦

结论

双接口,既满足脚本语言的使用方便性,又满足编译型语言的使用高效性。

于是,我们写的所有的 COM 组件接口,都用双接口实现吗?

错!否!NO!

如果不是明确非要支持脚本的调用,则最好不要使用双接口,因为:

如果所有函数都放在一个双接口中,那么层次、结构、分类不清

如果使用多个双接口,则会产生其它问题(注4)

双接口、IDispatch接口只支持自动化的参数类型,使用受到限制,某些情况下很不方便喽

还有很多弊病呦,不过现在我想不起来喽......

 

8、类型库:一种与语言无关的、适合解释性语言和宏编程语言使用的C++头文件的等价物。类型库将提供有关组件、接口、方法、属性、参数及结构的类型信息。类型库中的内容同C++头文件中的内容是相同的,他实际上是IDL文件的一个编译版本,并且可以用编程的方法来访问。类型库不是一个与语言无关的 需要被分析的文本文件,而是一个二进制文件。自动化库为创建和读取此二进制文件提供了一些标准的组件。

 

8、本章直接用随书提供的源码里的程序跑了一下,压根跑不起来。网上搜了搜,原来是因为注册类不支持汉字。移到没有汉字的路径下,就可以了。VC的工程源码在我的CSDN资源中可下载InsideCOM\CHAP11XXX。另外还有两种方式可以实现双接口:MFC和ATL。

 

你可能感兴趣的:(编程,c,服务器,脚本,mfc,语言)