Created
March 25, 2014 13:57
-
-
Save wyyqyl/9762380 to your computer and use it in GitHub Desktop.
QueryInterface, AddRef, Release
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <objbase.h> | |
#include <iostream> | |
interface IX : IUnknown { | |
virtual void Fx() = 0; | |
}; | |
interface IY : IUnknown { | |
virtual void Fy() = 0; | |
}; | |
interface IZ : IUnknown { | |
virtual void Fz() = 0; | |
}; | |
// {EDCC3AD9-E7ED-428F-ABF2-D4095E120315} | |
static const IID IID_IX = {0xedcc3ad9, | |
0xe7ed, | |
0x428f, | |
{0xab, 0xf2, 0xd4, 0x9, 0x5e, 0x12, 0x03, 0x15}}; | |
// {5EFDAA44-B1C7-4F45-B7B8-E94C7A6E43B6} | |
static const IID IID_IY = {0x5efdaa44, | |
0xb1c7, | |
0x4f45, | |
{0xb7, 0xb8, 0xe9, 0x4c, 0x7a, 0x6e, 0x43, 0xb6}}; | |
// {D89214D1-781E-4812-942A-76F600692E54} | |
static const IID IID_IZ = {0xd89214d1, | |
0x781e, | |
0x4812, | |
{0x94, 0x2a, 0x76, 0xf6, 0x00, 0x69, 0x2e, 0x54}}; | |
class CA : public IX, public IY { | |
virtual HRESULT STDMETHODCALLTYPE | |
QueryInterface(REFIID riid, _COM_Outptr_ void **ppvObject); | |
virtual ULONG STDMETHODCALLTYPE AddRef(); | |
virtual ULONG STDMETHODCALLTYPE Release(); | |
virtual void Fx() { std::cout << "Fx" << std::endl; } | |
virtual void Fy() { std::cout << "Fy" << std::endl; } | |
virtual void Fz() { std::cout << "Fz" << std::endl; } | |
public: | |
CA() : ref_count_(0) {} | |
private: | |
ULONG ref_count_; | |
}; | |
HRESULT STDMETHODCALLTYPE | |
CA::QueryInterface(REFIID riid, _COM_Outptr_ void **ppvObject) { | |
if (riid == IID_IUnknown) { | |
*ppvObject = static_cast<IX *>(this); | |
} else if (riid == IID_IX) { | |
*ppvObject = static_cast<IX *>(this); | |
} else if (riid == IID_IY) { | |
*ppvObject = static_cast<IY *>(this); | |
} else { | |
*ppvObject = NULL; | |
return E_NOINTERFACE; | |
} | |
(reinterpret_cast<IUnknown *>(*ppvObject))->AddRef(); | |
return S_OK; | |
} | |
ULONG STDMETHODCALLTYPE CA::AddRef() { | |
return InterlockedIncrement(&ref_count_); | |
} | |
ULONG STDMETHODCALLTYPE CA::Release() { | |
if (InterlockedDecrement(&ref_count_) == 0) { | |
delete this; | |
return 0; | |
} | |
return ref_count_; | |
} | |
IUnknown *CreateInstance() { | |
IUnknown *pI = static_cast<IX *>(new CA); | |
pI->AddRef(); | |
return pI; | |
} | |
int main() { | |
HRESULT hr = S_OK; | |
IUnknown *pIUnknown = CreateInstance(); | |
IX *pIX = NULL; | |
hr = pIUnknown->QueryInterface(IID_IX, (void **)&pIX); | |
if (SUCCEEDED(hr)) { | |
pIX->Fx(); | |
pIX->Release(); | |
} | |
IZ *pIZ = NULL; | |
hr = pIUnknown->QueryInterface(IID_IZ, (void **)&pIZ); | |
if (SUCCEEDED(hr)) { | |
pIZ->Fz(); | |
pIZ->Release(); | |
} else { | |
std::cout << "Couldn't get interface IID_IZ" << std::endl; | |
} | |
pIUnknown->Release(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment