QueryInterface

  1 // 08win32console-ATL.cpp : 定义控制台应用程序的入口点。

  2 //

  3 

  4 

  5 #include "stdafx.h"

  6 #include <objbase.h>

  7 #include <iostream>

  8 

  9 using std::cout;

 10 using std::endl;

 11 

 12 // {4FD945C1-9258-40d6-8370-738EF039C73D}

 13 static const IID IID_IX = 

 14 { 0x4fd945c1, 0x9258, 0x40d6, { 0x83, 0x70, 0x73, 0x8e, 0xf0, 0x39, 0xc7, 0x3d } };

 15 

 16 // {5765B41E-C0E5-47a2-81AF-ED8E5981327E}

 17 static const IID IID_IY = 

 18 { 0x5765b41e, 0xc0e5, 0x47a2, { 0x81, 0xaf, 0xed, 0x8e, 0x59, 0x81, 0x32, 0x7e } };

 19 

 20 // {81E64914-44CF-43e3-9660-E5AB7C64B045}

 21 static const IID IID_IZ = 

 22 { 0x81e64914, 0x44cf, 0x43e3, { 0x96, 0x60, 0xe5, 0xab, 0x7c, 0x64, 0xb0, 0x45 } };

 23 

 24 

 25 void trace(const char *pMsg) {cout << pMsg << endl;}

 26 

 27 interface IX : IUnknown{

 28     virtual void __stdcall Fx() = 0;

 29 };

 30 

 31 interface IY : IUnknown{

 32     virtual void __stdcall Fy() = 0;

 33 };

 34 

 35 interface IZ : IUnknown{

 36     virtual void __stdcall Fz() = 0;

 37 };

 38 

 39 class CA : public IX, public IY

 40 {

 41     virtual HRESULT __stdcall QueryInterface(const IID & iid, void ** ppv);

 42     virtual ULONG __stdcall AddRef() {return 0;}

 43     virtual ULONG __stdcall Release() {return 0;}

 44 

 45     virtual void __stdcall Fx() {cout << "CA::Fx" << endl;}

 46     virtual void __stdcall Fy() {cout << "CA::Fy" << endl;}

 47 };

 48 

 49 HRESULT __stdcall CA::QueryInterface(const IID & iid, void ** ppv)

 50 {

 51     if (iid == IID_IUnknown)

 52     {

 53         trace("QueryInterface: return pointer to IUnknown");

 54         *ppv = static_cast<IX *>(this); 

 55     }

 56     else if (iid == IID_IX)

 57     {

 58         trace("QueryInterface: return pointer to IX");

 59         *ppv = static_cast<IX *>(this);

 60     }

 61     else if (iid == IID_IY)

 62     {

 63         trace("QueryInterface: retrun pointer to IY");

 64         *ppv = static_cast<IY *>(this);

 65     }

 66     else

 67     {

 68         trace("QueryInterface: Interface not support");

 69         *ppv = NULL;

 70         return E_NOINTERFACE;

 71     }

 72     reinterpret_cast<IUnknown*>(*ppv)->AddRef();

 73 

 74     return S_OK;

 75 }

 76 

 77 IUnknown* CreateInstance()

 78 {

 79     IUnknown* pI = static_cast<IX *>(new CA);

 80     pI->AddRef();

 81     return pI;

 82 }

 83 

 84 int main()

 85 {

 86     HRESULT hr;

 87     trace("Client: Get an IUnknown pointer.");

 88     IUnknown * pUInknown = CreateInstance();

 89     

 90     trace("Client: Get interface IX.");

 91     IX * pIX = NULL;

 92     hr = pUInknown->QueryInterface(IID_IX, (void **)&pIX);

 93     if (SUCCEEDED(hr))

 94     {

 95         trace("Client: Succeeded getting IX");

 96         pIX->Fx();

 97     }

 98     

 99     trace("Client: Get interface IY.");

100     IY * pIY = NULL;

101     hr = pUInknown->QueryInterface(IID_IY, (void **)&pIY);

102     if (SUCCEEDED(hr))

103     {

104         trace("Client: Succeeded getting IY");

105         pIY->Fy();

106     }

107     

108     trace("Client: Get interface IZ");

109     IZ * pIZ = NULL;

110     hr = pUInknown->QueryInterface(IID_IZ, (void **)&pIZ);

111     if (FAILED(hr))

112     {

113         trace("Client: Cannot get interface IZ");

114     }

115     

116     trace("Client: Get interface IY from interface IX.");

117     IY * pIYfromIX = NULL;

118     hr = pIX->QueryInterface(IID_IY, (void **)&pIYfromIX);

119     if (SUCCEEDED(hr))

120     {

121         trace("Client: Succeeded getting IY");

122         pIYfromIX->Fy();

123     }

124     

125     trace("Client: Get interface IUnknown from IY");

126     IUnknown * pIUnknownfromIY = NULL;

127     hr = pIY->QueryInterface(IID_IUnknown, (void **)&pIUnknownfromIY);

128     if (SUCCEEDED(hr))

129     {

130         trace("Are the IUnknown pointers equal");

131         if (pIUnknownfromIY == pUInknown)

132             trace("Yes");

133         else

134             trace("No");

135     }

136     

137     delete pUInknown;

138     getchar();

139     return 0;

140 }

 

 

从其他任何接口都可以通过QueryInterface来实现CA所实现的任何接口

 

组件的实例只有一个IUnknown接口,因此要知道两个接口是否指向同一组件,只需通过这两个接口查询IUnknown接口,然后比较返回值即可。

 

C++相当于面试,基本情况简历一目了然

COM相当于社交,只有通过询问获取了解

客户无法获得COM的全部细节,不让客户了解COM的身份特征,可以使客户尽可能少的受组件改变的影响。

 

组件通过AddRef 和 Release来管理自己的生命周期(引用计数)

复制接口指针之后应该增加其引用计数

 

 

你可能感兴趣的:(interface)