IUnknown中的QueryInterface的实现剖析(1)

如题,写给我这样的COM初学者

QueryInterface的实现参考《COM技术内幕》p.35,我对里边的代码做了一些修改然后进行讲解。

// server.h
# ifndef SERVER_H
#  define SERVER_H
# include <ObjBase.h>
# include <iostream>
using namespace std;
inline void trace(const char* msg)
{
 cout << msg << endl;
}
// interface IUnknown
// IID_IX
extern const IID IID_IX;
 // Breakpoint:1
interface IX : IUnknown
{
 virtual void STDMETHODCALLTYPE display() = 0;
};
// IID_IY
extern const IID IID_IY;
interface IY : IUnknown
{
 virtual void STDMETHODCALLTYPE display() = 0;
};
// IID_IZ
extern const IID IID_IZ;
interface IZ : IUnknown
{
 virtual void STDMETHODCALLTYPE display() = 0;
};
class CX : public IX , public IY
{
public:
 // Breakpoint:2
 // from IUnknown
 HRESULT STDMETHODCALLTYPE QueryInterface(const IID& iid , void ** ppv);
 ULONG STDMETHODCALLTYPE AddRef(){return 0;}
 ULONG STDMETHODCALLTYPE Release(){return 0;}
 // from IX
 void STDMETHODCALLTYPE IX::display()
 {
  cout << "IX display!" << endl;
 }
 // from IY
 void STDMETHODCALLTYPE IY::display()
 {
  cout << "IY display!" << endl;
 }
};
# endif

// server.cpp
# include "server.h"

// IIDs
// {32bb8300-b41b-11cf-a6bb0080c7b2d682}
// {32bb8301-b41b-11cf-a6bb0080c7b2d682}
// {32bb8303-b41b-11cf-a6bb0080c7b2d682}
static const IID IID_IX = {
	0x32bb8300, 0xb41b, 0x11cf, {
		0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82
	}
};
static const IID IID_IY = {
	0x32bb8301, 0xb41b, 0x11cf, {
		0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82
	}
};
static const IID IID_IZ = {
	0x32bb8302, 0xb41b, 0x11cf, {
		0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82
	}
};

HRESULT CX::QueryInterface(const IID& iid , void ** ppv)
{
 
// Breakpoint:3
 
	*ppv = NULL;

	if(iid == IID_IUnknown)
	{
		trace("QueryInterface: Return pointer to IUnknown.");
		*ppv = static_cast<IUnknown*>(static_cast<IX*>(this));
	}
	if(iid == IID_IX)
	{
		trace("QueryInterface: Return pointer to IX.");
		*ppv = static_cast<IX*>(this);
	}
	if(iid == IID_IY)
	{
		trace("QueryInterface: Return pointer to IY.");
		*ppv = static_cast<IY*>(this);
	}
	if(NULL == *ppv)
	{
		trace("QueryInterface: Interface not found.");
		return E_NOINTERFACE;
	}

	reinterpret_cast<IUnknown*>(*ppv)->AddRef();
	return S_OK;
}
// server.cpp
///client code
# include "server.h"
void main()
{
 HRESULT hr;
 
// Breakpoint:4
 CX cpnt = CX();
 IUnknown * pIUnknown;
 pIUnknown = static_cast<IX*>(&cpnt);
 pIUnknown->AddRef();
 // Access IX from IX*
 IX * pIX = NULL;
 hr = pIUnknown->QueryInterface(IID_IX, (void **)&pIX);
 if(SUCCEEDED(hr))
 {
  trace("Succeeded getting IX.");
  pIX->display();
 }
 // Access IY from IY*
 IY * pIY = NULL;
 hr = pIUnknown->QueryInterface(IID_IY, (void **)&pIY);
 if( SUCCEEDED(hr))
 {
  trace("Succeeded getting IY");
  pIY->display();
 }
 // Access IZ
 IZ * pIZ = NULL;
 hr = pIUnknown->QueryInterface(IID_IZ, (void **)&pIZ);
 if( SUCCEEDED(hr))
 {
  trace("Succeeded getting IZ");
  pIZ->display();
 }
 pIUnknown->Release();
}


 

在上面的代码中设置了4个Breakpoints下面来分析下着四个断点。 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值