描述:
实现双接口的好处是?IDispatch接口是为了脚本里可以访问,那么实现了IDispatch接口后,为什么还要实现IUnknown接口?能举个例子么?
解决方案1:
补充一下luohualiushui(落花流水)的观点,
在VB中两种方式都有可能使用
声明为Object类型的变量使用IDispatch接口,
声明为具体的某个类的变量使用虚函数表
例如:
dim a as object
set a = CreateObject("aa.bb") 'VB内部将IDispatch接口指针赋值给变量a
a.func1(param1) '使用IDispatch提供的Invoke函数调用
dim b as aa.bb '声明的时候使用这种类型的前提是通过添加引用方式将类型库导入到VB工程中
set b = a '在这个赋值操作过程当中, VB内部调用QueryInterface函数得到相应额接口指针
b.func1(param1) '使用虚函数表调用
VB能够使用虚函数完全依赖于类型库(Type Library)
VBScript因为没有对Type Library的支持(由于VBScript是解释执行的所以向VB一样写程序的时候添加引用是不现实的), 所以只采用IDispatch接口提供的方法调用函数.
在这里想要阐述的重要观点是:
通过Type Library的支持, 可以使用虚函数表调用
通过IDispatch的支持, 可以使用IDispatch接口调用方法
继承自IDispatch的接口就是双重接口。
在ATL向导中,勾选“Custom”接口的,只能继承IUnknown接口。这样的接口,允许通过虚函数表绑定直接调用COM对象,这就要求使用C++这样的强类型语言,以便在编译时就确定要调用的方法和属性。
如果COM组件使用了IDispatch接口,那么,你当然也能使虚函数表绑定。然而,使用双接口你无需在编译时确定要调用的方法和属性就能够调用COM组件的方法。例如,对于COM组件里的getItem()方法,我们可以指明调用IDispatch::Inoke(),在运行时再将getItem名称作为参数传入,这样,就可以在运行时确定要调用的函数。当然,这种机制对于C++语言来说,几乎没什么用途。但是,对于像VBScript之类的脚本语言却是至关重要的,原因是它们是根本不进行类型检测的,所有的变量都只有一种类型:VARIANT。这类语言就只能通过自动化接口IDispatch调用组件对象的函数。
所以,双接口既实现了对VTable绑定的支持,又提供了对晚绑定的支持,使各种语言的COM客户都能够访问你的组件。
双接口指的是实现了IDISPATCH接口和c++的vtbl接口的接口,实现IDispatch接口正如楼上所言是为了满足多种语言的通讯用的,他提供了一种新的通讯方式,通过他组件可以向其它语言编写的客户程序提供com接口的服务。不过是以损失效率为代价的(调用invoke等函数是需要开销的)。而同时实现vtbl接口可以提供c++客户程序高效的要求。
实现IUnknown接口是必须的。每个组件都需要查询接口和计数控制功能。
直接调用接口函数的效率高,在可能的情况下应该直接通过接口调用函数
在vb以及一些脚本语言只能通过IDispatch调用
但在vc中两种调用方法都可以