IDispatchImplEx - 用于多接口分派的模板类






4.65/5 (9投票s)
用于实现 COM 对象的多接口分发的 C++ 模板类,基于 typeinfo 进行驱动,支持双接口和纯接口。
引言
模板类支持实现可脚本化的 COM 对象。可脚本化的对象必须实现 COM 接口 IDispatch
,而 ATL 通过模板类 IDispatchImpl
支持此接口。IDispatchImpl
仅支持对单个双接口进行分发。如果您的 COM 对象通过聚合或继承直接实现多个双接口,则 IDispatchImpl
会将分发限制为其中一个接口。此外,如果您的类仅实现非双接口(派生自 IUnknown
的接口),则 IDispatchImpl
将根本不起作用。
提供了两个模板类来实现多接口分发
IDispatchImplEx
- 替换ATL::IDispatchImpl
,并基于 typeinfo 对多个双接口进行分发。如果继承自此模板的类实现多个双接口,则很有用。该模板支持对聚合 COM 对象进行分发。PureDispatchImpl
- 用于实现纯IDispatch
接口,该接口基于 typeinfo 对一个或多个纯接口(派生自IUnknown
的接口)进行分发。
背景
ATL 包含模板类 IDispatchImpl
,它基于 typeinfo 对单个双接口(派生自 IDispatch
的接口)进行分发。
实现双接口的多接口分发
要实现多个双接口的多接口分发,请使用 IDispatchImplEx
代替 IDispatchImpl
class ATL_NO_VTABLE CMyClass :
public IProvideClassInfo2Impl<&CLSID_MyClass,&GUID_NULL, &LIBID_MyModule>,
public IDispatchImplEx<IMyInterface, &IID_IMyInterface,
&CLSID_MyClass, &LIBID_MyModule>,
如果接口定义在导入的类型库中,这仍然有效
class ATL_NO_VTABLE CMyClass :
public IProvideClassInfo2Impl<&CLSID_MyClass,&GUID_NULL, &LIBID_MyModule>,
public IDispatchImplEx<IMyInterface, &IID_IMyInterface,
&CLSID_MyClass, &LIBID_ImportedLib>,
如果您的类支持事件,请在 IProvideClassInfo2Impl
模板中将 GUID_NULL
替换为您的事件接口的 IID。
实现对一个或多个纯接口的分发
要实现对一个或多个派生自 IUnknown
的纯接口的多接口分发,请使用 PureDispatchImpl
。该实现向类添加单个 IDispatch
实现,并使用 typeinfo 对纯接口进行分发。但是,有一个要求,即接口必须提供 type info。
class ATL_NO_VTABLE CMyClassWithNoDuals :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyClassWithNoDuals, &CLSID_MyClassWithNoDuals>,
public PureDispatchImpl<&CLSID_MyClassWithNoDuals, &LIBID_MyLib>,
public IPure1,
public IPure2,
示例代码:
IDL 代码
importlib("ImportedLib.tlb"); // Interface IC is defined here
//Dual interface definitions
interface IA : IDispatch
{
HRESULT MethodOnIA();
};
interface IB : IDispatch
{
HRESULT MethodOnIB();
};
// Pure (non-dual) interface definitions
interface IPure1 : IUnknown
{
HRESULT DispMe();
};
interface IPure2 : IUnknown
{
HRESULT DispMeAgain();
};
// Class definitions
// MyClass implements three dual interfaces,
// one defined in an imported type library
coclass MyClass
{
[default] interface IA;
interface IB;
interface IC; // Defined in ImportedLib.tlb
};
// MyClassWithNoDuals implements three pure interfaces,
// one of them defined in an imported type library
coclass MyClassWithNoDuals
{
[default] interface IPure1;
interface IPure2;
interface ID; // Defined in ImportedLib.tlb
};
C++ 实现
// Implementation of class with multiple dual interfaces
class ATL_NO_VTABLE CMyClass :
public CComObjectRootEx<CComSingleThreadModel>,
public IProvideClassInfo2Impl<&CLSID_MyClass,&GUID_NULL, &LIBID_MyLib>,
public IDispatchImplEx<IA, &IID_IA, &CLSID_MyClass, &LIBID_MyLib>,
public IDispatchImplEx<IB, &IID_IB, &CLSID_MyClass, &LIBID_MyLib>,
public IDispatchImplEx<IC, &IID_IC, &CLSID_MyClass, &LIBID_ImportedLib>,
public CComCoClass<CMyClass, &CLSID_MyClass>,
public ISupportErrorInfo
{
..standard ATL implementation
// Implementation of class with multiple pure interfaces
class ATL_NO_VTABLE CMyClassWithNoDuals :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyClassWithNoDuals, &CLSID_MyClassWithNoDuals>,
public PureDispatchImpl<&CLSID_MyClassWithNoDuals, &LIBID_MyLib>,
public IPure1,
public IPure2,
public ID,
public ISupportErrorInfo,
{
..standard ATL implementation
BEGIN_COM_MAP(CMyClassWithNoDuals)
COM_INTERFACE_ENTRY(IPure1)
COM_INTERFACE_ENTRY(IPure2)
COM_INTERFACE_ENTRY(ID)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()
...standard implementation
脚本示例,VB 脚本客户端
Dim instanceOfMyClass
... got instanceOfMyClass from somewhere
' Regardless of which interface I got hold of,
' I can script towards all methods on the class:
instanceOfMyClass.MethodOnIA
instanceOfMyClass.MethodOnIB
instanceOfMyClass.MethodOnIC
Dim instanceOfMyClassWithNoDuals
... got instanceOfMyClassWithNoDuals from somewhere
' Regardless of which interface I got hold of,
' I can script towards all methods on the class:
instanceOfMyClassWithNoDuals.DispMe
instanceOfMyClassWithNoDuals.DispMeAgain
instanceOfMyClassWithNoDuals.MethodOnID
历史
- 1.0 - 1998-05-07:初始版本。
- 2.0 - 1998-11-19:转换为 ATL 3.0。
- 3.0 - 1999-07-10:如果已实现,则使用
IProvideClassInfo
。 - 4.0 - 2002-11-14:支持实现纯
IDispatch
实现;添加了PureDispatchImpl
。