如题,写给我这样的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();
}