// 完整的COM例子
#include <unknwn.h>
#include <iostream.h>
#include <objbase.h>
void Trace (const char* msg)
{
cout << msg << endl;
}
/*注意这里为了实现多态都接口都使用了虚函数*/
/*使用_stdcall支持DLL调用*/
// interface
interface IX : IUnknown
{
virtual void _stdcall Fx() = 0;
};
interface IY : IUnknown
{
virtual void _stdcall Fy() = 0;
};
interface IZ : IUnknown
{
virtual void _stdcall Fz() = 0;
};
// Forward references for GUIDs
extern const IID IDD_IX;
extern const IID IDD_IY;
extern const IID IDD_IZ;
// component
class CA : public IX,
public IY
{
/*从接口继承而来的都应该是虚函数,由于基类已经声明了virtual关键字,这里可以省略*/
public:
// IUnknown
HRESULT _stdcall QueryInterface (const IID& iid, void ** ppv);
ULONG _stdcall AddRef (void)
{
return 0;
}
ULONG _stdcall Release(void)
{
return 0;
}
// IX
void _stdcall Fx()
{
cout << "Fx" << endl;
}
// IY
void _stdcall Fy()
{
cout << "Fy" << endl;
}
};
// GUID
// {6134635D-4669-4c4b-BEB3-9223591AE918}
static const GUID IID_IX =
{ 0x6134635d, 0x4669, 0x4c4b, { 0xbe, 0xb3, 0x92, 0x23, 0x59, 0x1a, 0xe9, 0x18 } };
// {D90FD541-D995-4303-9A07-1CC54C6BA576}
static const GUID IID_IY =
{ 0xd90fd541, 0xd995, 0x4303, { 0x9a, 0x7, 0x1c, 0xc5, 0x4c, 0x6b, 0xa5, 0x76 } };
// {F881374D-98D7-48a2-AA72-373A988AF3D9}
static const GUID IID_IZ =
{ 0xf881374d, 0x98d7, 0x48a2, { 0xaa, 0x72, 0x37, 0x3a, 0x98, 0x8a, 0xf3, 0xd9 } };
HRESULT _stdcall CA::QueryInterface(const IID& iid, void ** ppv)
{
if(IID_IUnknown == iid)
{
Trace("QueryInterface: return pointer to IUnknow.");
// *ppv = static_cast<IUnknown* > (this); IUnknown是一个虚类不能产生实例
*ppv = static_cast<IX* > (this);
}
else if(IID_IX == iid)
{
Trace("QueryInterface: return pointer to IX.");
*ppv = static_cast<IX* > (this);
}
else if(IID_IY == iid)
{
Trace("QueryInterface: return pointer to IY.");
*ppv = static_cast<IY* > (this);
}
else
{
Trace("QueryInterface: no interface.");
*ppv = NULL;
return E_NOINTERFACE;
}
// reinterpret_cast操作符修改了操作数类型,但仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换
reinterpret_cast<IUnknown* > (*ppv)->AddRef(); // 疑问
return S_OK;
}
// Creation function
IUnknown * CreateInstance()
{
IUnknown * pI = static_cast<IX*>(new CA);
pI->AddRef();
return pI;
}
int main()
{
HRESULT hr;
// 方式一
Trace("Client: Get an IUnKnow pointer");
IUnknown * pIUnknown = CreateInstance();
Trace("Client: Get interface IX");
// 方式二
// 获取IX
IX * pIX = NULL;
hr = pIUnknown->QueryInterface(IID_IX, (void**)&pIX);
if(SUCCEEDED(hr))
{
Trace("Client: Succeeded getting IX");
pIX->Fx(); // Use interface IX
}
else
{
Trace("Client: Could not get interface IX");
}
// 获取IY
IY * pIY = NULL;
hr = pIUnknown->QueryInterface(IID_IY, (void**)&pIY);
if(SUCCEEDED(hr))
{
Trace("Client: Succeeded getting IY");
pIY->Fy(); // Use interface IY
}
else
{
Trace("Client: Could not get interface IY");
}
Trace("Client: ask for an unsupported interface");
IZ * pIZ = NULL;
hr = pIUnknown->QueryInterface(IID_IZ, (void**)&pIZ);
if(SUCCEEDED(hr))
{
Trace("Client: Succeeded getting IZ");
pIX->Fx(); // Use interface IX
}
else
{
Trace("Client: Could not get interface IZ");
}
Trace("Client: Get interface IY from interface IX");
IY * pIYfromIX = NULL;
hr = pIX->QueryInterface(IID_IY, (void**)&pIYfromIX);
if(SUCCEEDED(hr))
{
Trace("Client: Succeeded getting IY");
pIYfromIX->Fy();
}
IUnknown * pIUnknownFromIY = NULL;
hr = pIY->QueryInterface(IID_IUnknown, (void**)&pIUnknownFromIY);
if(SUCCEEDED(hr))
{
cout << "are the IUnknown pointers equal ?" << endl;
if(pIUnknownFromIY == pIUnknown)
{
cout << "yes,pIUnknownFromIY == pIUnknown" << endl;
}
else
{
cout << "no,pIUnknownFromIY != pIUnknown" << endl;
}
}
delete pIUnknown;
}