关于IDispatch接口的二个问题

xhncmecx 2004-04-17 12:20:23
一、IDispatch接口从IUnknow接口继承而来,我的问题是,一个自动化对象实现了IDispatch接口,为什么要实现IDispatch接口中的 AddRef、Release、QueryInterFace 三个虚函数?只需要从IUnknow接口中实现了它们,并继承过来不就可以了吗?

二、如果实现了IDispatch接口(包括AddRef、Release、QueryInterFace等三个虚函数),IDispatch已经包含了IUnknow的一切,有必要再实现IUnknow接口吗?。
...全文
134 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
itmaster 2004-04-17
  • 打赏
  • 举报
回复
IDispatch接口作为自动化对象的重要特征,可以通过QuereyInterface()函数查询此接口来确定组件是否是自动化对象。IDispatch接口直接从IUnknown接口派生,接口定义如下:

interface IDispatch : IUnknown
{
 virtual HRESULT GetTypeInfoCount(UINT* pctinfo) = 0;
 virtual HRESULT GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) = 0;
 virtual HRESULT GetIDsOfNames (REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) = 0;
 virtual HRESULT Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr ) = 0;
}

  其中,接口成员函数GetTypeInfoCount()用于获取自动化组件支持的ITypeInfo接口的数目。GetTypeInfo()用于获取指针ITypeInfo接口的指针,通过该指针将能够判断自动化服务程序所提供的自动化支持。剩下的这两个函数是比较重要的,其中GetIDsOfNames()将读取一个函数的名称并返回其调度ID(DISPID),DISPID只是一个long类型的数据,对于IDispatch的一个特定实现,此DISPID值应该是唯一的。其参数riid为保留参数,必须设置为IID_NULL,在rgszNames中指定了成员的函数名及其参数,由cNames标识了名字的个数,lcid参数用于指定本地化标识,得到的DISPID 将保存到rgdispid中。Invoke()提供了访问自动化对象暴露出来的方法和属性的方法。可以将DISPID作为函数指针数组的索引传入dispidMember参数,Invoke()将实现一组按此索引来访问的函数。riid和lcid的含义与在GetIDsOfNames()中的定义相同,分别为保留参数和本地化标识。WFlags参数指定了要访问的是接口的属性还是方法,pdispparams参数包括了方法和属性调用的参数数组、DISPID数组以及数组中参数个数等信息。pvarResult参数保存有返回值信息。pexcepinfo指向一个有效的异常信息结构,puArgErr参数包含了第一个产生错误的参数指针。通过GetIDsOfNames()和Invoke()的结合使用,将可以根据函数名称对方法和属性进行调用。这样,函数地址、AddRef()、Release()以及接口指针等细节问题将无需考虑。
_foo 2004-04-17
  • 打赏
  • 举报
回复
关于第二个问题,事实上IDispatch接口是IUnknown的超集。你实现IDispatch的同时就是实现了IUnknown接口
_foo 2004-04-17
  • 打赏
  • 举报
回复
一、
一切的实现都是在实现类中实现的.而不是在接口中实现的.所以,一个自动化对象实现了IDispatch接口,而IDispatch又是从IUnknown继承而来,理所当然这个自动化必须实现这三个函数.如果把实现推给IUnknown去做,第一,破坏了接口只是一个调用约定这样一个事实.第二,IUnknown不可能知道你的自动化对象会实现几个接口,那么他的QueryIntrFace怎么实现??

二,当然是没必要的,本来就是这样子。
xhncmecx 2004-04-17
  • 打赏
  • 举报
回复
好的,谢谢 _foo(void),给分
_foo 2004-04-17
  • 打赏
  • 举报
回复
呵呵,如果你初学COM,最好别把MFC扯进来。MFC里面很多东东是为了实现其他功能的。而不是IDispatch的范畴。
xhncmecx 2004-04-17
  • 打赏
  • 举报
回复
To:_foo(void)

关于第二个问题,我还是有点疑问,CCmdTarget类定义中有以下两个数据成员

LPUNKNOWN m_pOuterUnknown;
DWORD m_xInnerUnknown;

也就是说,不管实现什么接口的同时,都会实现IUnknow接口,也就是说实现了IDispatch接口,也要实现IUnknow接口,不知我的看法对不对?

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧