《COM技术内幕》FAQ
sunshineormer@msn.com
读书问题一:
第11章,分发接口与自动化P231
"自动化在许多不同的方面用开发人员编写的代码来代替编译器生成的代码"
请问这句话如何理解?
答:
这句话没有问题:
大意是说,我们原先所写的应用,都是源码一级,需要经过编译器编译,才能执行,现在,用脚本语言来操作自动化接口,可以动态的完成相同的应用(其实是解释执行)。
一个简单的例子,你肯定没有Word的源码,如果你象用Word来生成一个针对于具体应用领域(比方说政府公文)的应用,你只能找有源码的公司来修改源码,以适应你的特殊需要。(微软听你的?)
但是,你可以用自动化接口来定制你的特定应用,用 VBA脚本来控制Word的自动化接口就可以完成。是的,解释执行是慢了些,但是,对你来说不用改源码,不用再去测试你修改的源码部分,不是更好吗?
读书问题二:
第11章,分发接口与自动化P234
若C++程序员想在运行时从头开始构造一个vtbl,那他可以完全自行决定如何构造。另一方面..."
这段话应如何理解?
答:
是的,一个VTBLE的生成是由你所用的编译器替你完成的,但是,如果你明白了 vtbl的构造过程,你可以仿制一个出来.
建议读:com本质论+ inside c++ object model
要有很好的心理准备,啃硬骨头
读书问题三:
OleInitialize于CoInitialize(Ex)这两个函数有什么区别?
P236倒数第六行有对OleInitialize的调用
答:
CoInitialize CoInitializeEx 是用来初始化COM运行环境的,就象练武的人在练武前先划了个圈,在圈里摆上了兵器()
OleInitialize是初始化Ole的运行环境,Ole是在Com的基础上作的扩展,是ActiveX运行的基础。就向是在刚才的圈子里撑起了个钢丝,要表演钢丝上的表演一样。
读书问题之四:
p208页:关于对point_default关键字的解释,看不懂)
1."point_default关键字地作用就是告诉MIDL编译器在没有为指针指定其它属性时应如何处理此指针”, “其它属性”都是些什么?
2. "在函数内部,不能为它们指定别名”,什么是别名?
答:
至于别名,是指midl语言中的typedef吧(非常抱歉,我对COM的调度部分没有太多的关注,只能简单回答,请你有了明确的答案后告诉我)。
读书问题之五:
p234最后一句:“当然用COM接口来实现IDispatch::Invoke也是可能的,请参阅图11-2。”
1. 用Com接口如何实现Invoke?
2. 图11-2中FooBar不是Com接口吧(没有IUnknown那三个函数).
答:
com是更好的C++,Com 的实现其实借鉴了很多C++的实现方式,比如,利用我前面所说的vtbl,
按照规定,我觉得我们不应该把 图11-2 的FooBar称为COM接口,但是,在广义的范围内,由于使用了vtbl,可以勉强认为他也是一个COM接口,(如果作者非要这样讲的话^_^)
读书问题之六:
分发接口是Com接口(符合COM接口的定义吗)?它跟Invoke函数有何关系?如果不是Com接口,那么分发接口的定义是什么?
答:
分发接口可以是COM接口,也可以不是,这只是实现时的不同方式而已,分发接口是一个概念,内部应该包含两个数组,一个存放dispid与接口方法名称的对值(pair),一个存放的是dispid与接口方法指针(也就是函数指针)的对值。只要有这两部分我们就认为它是一个分发接口,至于是不是COM接口,那都无所谓。
Invoke的时候,需要提供dispid和对应的参数,这样,就可以用利用分发接口的具体实现机制得到函数指针进行功能调用了。
读书问题之七:
p234第七行:“IDispatch::Invoke的一个实现所实现的函数集被称作一个分发接口,和dispinterface"。Invoke是一个函数,怎么能够实现”函数集“?
Invoke函数跟分发接口之间是什么关系?
对于IDispatch::Invoke ,我们可以看一下它的运行过程
在调用Invoke之前,我们通过各种方式得到了一个dispid,(不要以为只有GetIDsOfNames才能得到,我曾经在一个组件里实现了根据状态不同动态的将可执行的dispid传出,然后在组件内提供了一个方法,ExecuteCmd(dispid),这样客户程序也可以动态执行组件的接口方法了)。接口的本质就是一组函数指针的数组,而dispid就是函数指针数组的索引(注意,只有实现IDispatch接口才有dispid),通过指定索引,我们可以得到指定的函数指针,这样我们可以用(*函数指针)(参数,参数…)的方式来调用具体的接口方法了。
“等等”我听见你在喊,“我们的参数是以数组的形式传进来的,而你用函数指针调用的时候是用参数列表的形式调用的,我要怎样才能实现它呢?”
是的,如果要你自己写一个Invoke的实现,光参数的压栈和类型处理就会累死你的,告诉你一个好办法,用ms的api函数(DispCallFunc 或者 DispInvoke),或者用使用mfc/atl对IDispatch实现的封装(mfc用的是一个helper ,而Atl用的是IdispatchImpl 模版)
分发接口,是一个逻辑概念,是指有个地方存放了函数方法名和函数的指针,通过这个接口,你可以用指定的方法名来检索到函数的指针,最大的用处,是提供给脚本解释器使用。