QueryInterface

QueryInterface

QueryInterface, , , C++. , , . . , , IID - , - . , QueryInterface, , , if, static_cast (static_cast , vptr).

QueryInterface, , . , IID , vptr . , , . inttable.h, :

 // inttable.h (book-specific header file) // inttable.h (   ,        )  // typedef for extensibility function  // typedef        typedef HRESULT (*INTERFACE_FINDER)  (void *pThis, DWORD dwData, REFIID riid, void **ppv);  // pseudo-function to indicate entry is just offset  //        ,        //      #define ENTRY_IS_OFFSET INTERFACE_FINDER(-1)  // basic table layout  //        typedef struct INTERFACE_ENTRY {      const IID * pIID;        // the IID to match        //   IID      INTERFACE_FINDER pfnFinder;        //   finder      DWORD dwData;        // offset/aux data       //     offset/aux  } INTERFACE_ENTRY;  

:

 // Inttable.h (book-specific header file) // Inttable.h (   ,        )  #define BASE_OFFSET(ClassName, BaseName) \  (DWORD(static_cast<BaseName*>(reinterpret_cast\  <ClassName*>(0x10000000))) - 0 10000000)  #define BEGIN_INTERFACE_TABLE(ClassName) \  typedef ClassName _ITCls;\  const INTERFACE_ENTRY *GetInterfaceTable(void) {\  static const INTERFACE_ENTRY table [] = {\  #define IMPLEMENTS_INTERFACE(Itf) \  {&IID_##Itf,ENTRY_IS_OFFSET,BASE_OFFSET(_ITCls,Itf)},  #define IMPLEMENTS_INTERFACE_AS(req, Itf) \  {&IID_##req,ENTRY_IS_OFFSET, BASE_OFFSET(_ITCls, Itf)},  #define END_INTERFACE_TABLE() \  { 0, 0, 0 } }; return table; }  

, , , QueryInterface. Inttable.h:

 // inttable.cpp (book-specific source file) // inttable.h (   ,        )  HRESULT InterfaceTableQueryInterface(void *pThis,                                       const INTERFACE_ENTRY *pTable,                                       REFIID riid, void **ppv)  {      if (InlineIsEqualGUID(riid, IID_IUnknown)) {          // first entry must be an offset          //                    *ppv = (char*)pThis + pTable->dwData;          ((Unknown*) (*ppv))->AddRef () ; // A2          return S_OK;      }      else {          HRESULT hr = E_NOINTERFACE;          while (pTable->pfnFinder) { // null fn ptr == EOT              if (!pTable->pIID || InlineIsEqualGUID(riid,*pTable->pIID)) {                  if (pTable->pfnFinder == ENTRY_IS_OFFSET) {                      *ppv = (char*)pThis + pTable->dwData;                      ((IUnknown*)(*ppv))->AddRef(); // A2                      hr = S_OK;                      break;                  }                  else {                      hr = pTable->pfnFinder(pThis, pTable->dwData, riid, ppv);                      if (hr == S_OK) break;                  }               }               pTable++;          }          if (hr != S_OK) *ppv = 0;          return hr;      }  }  

, InterfaceTableQueryInterface , IID, , . IsEqualGUID, , 20-30 , . InterfaceTableQueryInterface , .

C++, , - . impunk.h QueryInterface, AddRef Release , :

 // impunk.h (book-specific header file) // impunk.h (   ,        )  // AUTO_LONG is just a long that constructs to zero  // AUTO_LONG -     long,    ,  //          struct AUTO_LONG {      LONG value;      AUTO_LONG (void) : value (0) {}  };  #define IMPLEMENT_UNKNOWN(ClassName) \  AUTO_LONG m_cRef;\  STDMETHODIMP QueryInterface(REFIID riid, void **ppv){\  return InterfaceTableQueryInterface(this,\  GetInterfaceTable(), riid, ppv);\  }\  STDMETHODIMP_(ULONG) AddRef(void) { \  return InterlockedIncrement(&m_cRef.value); \  }\  STDMETHODIMP_(ULONG) Release(void) {\  ULONG res = InterlockedDecrement(&m_cRef.value) ;\  if (res == 0) \  delete this;\  return res;\  }\  

, .

PugCat, , QueryInterface, AddRef Release :

 class PugCat : public IPug, public ICat {   protected:      virtual ~PugCat(void);    public:      PugCat(void);        // IUnknown methods        //   IUnknown      IMPLEMENT_UNKNOWN (PugCat)      BEGIN_INTERFACE_TABLE(PugCat)        IMPLEMENTS_INTERFACE(IPug)        IMPLEMENTS_INTERFACE(IDog)        IMPLEMENTS_INTERFACE_AS(IAnimal,IDog)        IMPLEMENTS_INTERFACE(ICat)     END_INTERFACE_TABLE()        // IAnimal methods        //   IAnimal      STDMETHODIMP Eat(void);        // IDog methods        //   IDog      STDMETHODIMP Bark(void);        // IPug methods        //   IPug      STDMETHODIMP Snore(void);        // ICat methods        //   ICat      STDMETHODIMP IgnoreMaster(void);  };  

, IUnknown . , , , .



Suschnost' tehnologii SOM
Essential COM
ISBN: 0201634465
EAN: 2147483647
Year: N/A
Pages: 103
Authors: Don Box

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net