荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: oopilix (冬眠的抽象实例), 信区: Visual
标  题: [zz]《COM技术内幕》学习笔记(7)
发信站: 荔园晨风BBS站 (Mon Oct 20 13:30:33 2003), 站内信件


原作者姓名 雷神
文章原始出处 http://www.ai361.com

介绍
同样是调用ADO组件,VB、VC、JAVA脚本、VB脚本之间的差距咋就那么大呢?一直
以来我都搞不明白这个问题。

正文
第七部分:
    同样是调用ADO组件,VB、VC、JAVA脚本、VB脚本之间的差距咋就那么大呢?
一直以来我都搞不明白这个问题。现在也许可以明白了,因为第十一章就是要说说
组件和客户之间进行通讯的三种方式。分别是:vtbl接口,双接口和分发接口。
    若组件被编译型语言如C或C++访问,可以使用vtbl或常规的COM接口,它比分
发接口要快的多。如果组件将被VB或JAVA访问,那应该实现一个双接口。对于进程
内组件vtbl接口比分发接口快上100倍,对于进程外组件,vtbl接口仅比分发接口
快2.5倍。对远程组件,各种类型的接口几乎没有任何差别。这是不是能说明如果
用VC+ADO数据库应用程序,效率要比VB高很多呢?

FAQ49:什么是IDispatch(分发接口)?〖第十一章〗
FAQ50:什么是双接口?〖第十一章〗
FAQ51:关于IDispatch?〖第十一章〗
FAQ52:关于VARIANT结构?〖第十一章〗
FAQ53:关于BSTR和SAFEARRY类型?〖第十一章〗
FAQ54:什么是类型库?〖第十一章〗

Question:
    什么是IDispatch(分发接口)?
Answer:
    IDispatch为客户和组件提供一个标准的接口。
    通过IDispatch接口可以提供它所支持的服务,而无需提供多个特定于服务的
接口。
    IDispatch接收一个函数名称并执行这个函数。
    IDispatch的成员函数GetIDsOfNames读取一个函数的名称并返回其分发ID,或
称DISPID。
    DISPID不是一个GUID,它是一个长整数,它标识的是一个函数。对特定的实现
它是唯一的。
    IDispatch的每一个实现都有其自己的IID(有些人称DIID,即分发接口ID)
    自动化控制程序把DISPID传给IDispatch的成员函数Invoke。
    Invoke根据接收到的DISPID决定执行行为。
    IDispatch::Invoke实现一个与vtbl相似的一组按索引访问的函数。
    IDispatch::Invoke的一个实现所实现的函数集被称为分发接口。
    对于分发接口,我们可以将传给GetIDsOfNames的名称作为一个哈希表的关键
字,这样系统的效率会更高。

Question:
    什么是双接口?
Answer:
    让实现IDispatch::Invoke的COM接口继承于IDispatch而不是IUnknown,则
就实现双接口类型的接口方法。
    双接口也是一种分发接口。
    双接口可以通过Invoke访问函数也能直接通过vtbl访问函数。

Question:
    关于IDispatch?
Answer:
    IDispatch是一个COM接口。
    编译器在编译时刻生成对IDispatch成员的调用代码,这些代码是静态的。
    但是传给Invoke的参数是动态的,并且参数决定调用的函数。
    IDispatch::Invoke的任务之一是把参数传给将要被执行的函数。
    Invoke函数的参数如下:
第一个参数是控制程序待调用函数的DISPID;
第二个参数是保留的必须是IID_NULL;
第三个参数保存的是位置信息;
第四个参数是提供类型信息的;
第五个参数是一个结构DISPPARAMS包含的是传递被调用函数的参数;
第六个参数pVarResult为一个指向VARIANT结构的指针,用于保存所执行的方法或
propget的结果;第七个参数是一个指向EXCEPINFO结构的指针;
第八个参数是如果返回值为DISP_E_PARAMNOTFOUND或DISP_E_TYPEMISMATCH则将错
误相对应的参数的索引保存在最后一个参数puArgErr中

Question:
    关于VARIANT结构?
Answer:
    VARIANT和VARIANTARG结构相同。
    VARIANT和VARIANTARG结构的定义可以在OAIDL.IDL中找到。
    VARIANT结构的初始化是借助函数VariantInit完成的。
    使用VARIANT可以完全摆脱静态类型检查。
    VARIANT值的类型转换由分发接口完成。
    自动化提供了一个名为VariantChangeType的函数来完成转换。
    如果我们不想提供一个值,只需传递一个vt域被设成VT _ERROR、而且scode被
设置成DISP_E_PARAMNOTFOUND的VARIANT结构即可。

Question:
    关于BSTR和SAFEARRY类型?
Answer:
    BSTR是Basic字符串(Basic String)或二进制字符串(Binay String )的缩
写。
    BSTR实际上是一个指向宽字符串的指针。
    BSTR是一个带有字符记数值的字符串。
    字符记数值保存在字符数组的前面,可以使用SysAllocString(WIN32 API)
函数给BSTR变量赋值。
    分配了一个BSTR结构后,还需要用SysFreeString将其释放。
    BSTR实际上就是一个wchar_t串。
    它所包含的字符串中可以有多个“\0”。
    SAFEARRY是一个包含有边界信息的数组。
    SAFEARRY的类型定义也可以从OAIDL.IDL中找到。
    自动化库OLEAUTL32.DLL包含许多操作SAFEARRY的函数。

Question:
    什么是类型库?
Answer:
    类型库可以提供组件、接口、方法、属性、参数及结构的类型信息。
    类型库实际上是IDL文件的编译版本,并且可以用编程的方法来访问。
    类型库是一个二进制文件,自动化库为创建和读取此二进制文件提供了一些标
准的组件。
    自动化库函数CreateTypeLib可以创建一个类型库,该函数将返回一个


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店