Skip to content

Instantly share code, notes, and snippets.

@wyyqyl
Created March 25, 2014 13:57
Show Gist options
  • Save wyyqyl/9762380 to your computer and use it in GitHub Desktop.
Save wyyqyl/9762380 to your computer and use it in GitHub Desktop.
QueryInterface, AddRef, Release
#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