#include <objbase.h>
interface ICalcu : IUnknown
{
virtual int __stdcall Sum(int x, int y) = 0;
virtual int __stdcall Sub(int x, int y) = 0;
virtual int __stdcall Mul(int x, int y) = 0;
virtual double __stdcall Div(int x, int y) = 0;
};
interface IRadius : IUnknown
{
virtual double __stdcall Radius(int x, int y) = 0;
};
HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter,
const IID& iid,
void** ppv)
{
if(pUnknownOuter != NULL)
{
return CLASS_E_NOAGGREGATION;
}
CSimpleCalc2* pSc = new CSimpleCalc2;
if(pSc == NULL)
{
return E_OUTOFMEMORY;
}
HRESULT hr = pSc->InitAggregation() ;
if (FAILED(hr))
{
pSc->Release() ;
return hr ;
}
/* HRESULT */hr = pSc->QueryInterface(iid,ppv);
pSc->Release();
return hr;
}
#include "interface.h"
class CSimpleCalc2 : public IRadius
{
public:
...
HRESULT InitAggregation() ;
private:
...
IUnknown* m_pUnknownInner;
};
CSimpleCalc2::~CSimpleCalc2()
{
InterlockedDecrement(&g_cComponents);
...
if (m_pUnknownInner != NULL)
{
m_pUnknownInner->Release() ;
}
}
HRESULT CSimpleCalc2::InitAggregation()
{
IUnknown* pUnknownOuter = this;
HRESULT hr = ::CoCreateInstance(CLSID_COMPONENT,
pUnknownOuter,
CLSCTX_INPROC_SERVER,
IID_IUnknown,
(void**)&m_pUnknownInner) ;
if (FAILED(hr))
{
return E_FAIL ;
}
...
return S_OK ;
}
HRESULT __stdcall CSimpleCalc2::QueryInterface(const IID& iid, void** ppv)
{
if(iid == IID_IUnknown)
{
*ppv = static_cast<IRadius*>(this);
}
else if(iid == IID_IRadius)
{
*ppv = static_cast<IRadius*>(this);
}
// {
else if (iid == IID_ICalcu)
{
return m_pUnknownInner->QueryInterface(iid,ppv) ;
}
// }
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
static_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
#include <objbase.h>
interface ICalcu : IUnknown
{
virtual int __stdcall Sum(int x, int y) = 0;
virtual int __stdcall Sub(int x, int y) = 0;
virtual int __stdcall Mul(int x, int y) = 0;
virtual double __stdcall Div(int x, int y) = 0;
};
HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter,
const IID& iid,
void** ppv)
{
if((pUnknownOuter != NULL) && (iid != IID_IUnknown))
{
return CLASS_E_NOAGGREGATION;
}
CSimpleCalc* pSc = new CSimpleCalc(pUnknownOuter);
if(pSc == NULL)
{
return E_OUTOFMEMORY;
}
HRESULT hr = pSc->NondelegatingQueryInterface(iid,ppv);
pSc->NondelegatingRelease();
return hr;
}
#include "interface.h"
struct INondelegatingUnknown
{
virtual HRESULT __stdcall
NondelegatingQueryInterface(const IID&, void**) = 0 ;
virtual ULONG __stdcall NondelegatingAddRef() = 0 ;
virtual ULONG __stdcall NondelegatingRelease() = 0 ;
} ;
class CSimpleCalc : public ICalcu, public INondelegatingUnknown
{
public:
// IUnknown
virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv)
{
return m_pUnknownOuter->QueryInterface(iid, ppv) ;
}
virtual ULONG __stdcall AddRef()
{
return m_pUnknownOuter->AddRef() ;
}
virtual ULONG __stdcall Release()
{
return m_pUnknownOuter->Release() ;
}
// Nondelegating IUnknown
virtual HRESULT __stdcall NondelegatingQueryInterface(const IID& iid, void** ppv) ;
virtual ULONG __stdcall NondelegatingAddRef() ;
virtual ULONG __stdcall NondelegatingRelease() ;
CSimpleCalc(IUnknown* pUnknownOuter);
...
// ICalcu
virtual int __stdcall Sum(int x, int y)
{
return x + y;
}
virtual int __stdcall Sub(int x, int y)
{
return x - y;
}
virtual int __stdcall Mul(int x, int y)
{
return x * y;
}
virtual double __stdcall Div(int x, int y)
{
return x / y;
}
private:
...
IUnknown* m_pUnknownOuter;
};
#include "SimpleCalc.h"
CSimpleCalc::CSimpleCalc(IUnknown* pUnknownOuter) : m_cRef(1)
{
...
if (pUnknownOuter == NULL)
{
m_pUnknownOuter = reinterpret_cast<IUnknown*>
(static_cast<INondelegatingUnknown*>
(this)) ;
}
else
{
m_pUnknownOuter = pUnknownOuter ;
}
}
HRESULT __stdcall CSimpleCalc::NondelegatingQueryInterface(const IID& iid, void** ppv)
{
if(iid == IID_IUnknown)
{
*ppv = static_cast<INondelegatingUnknown*>(this);
}
else if(iid == IID_ICalcu)
{
*ppv = static_cast<ICalcu*>(this);
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
static_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
ULONG __stdcall CSimpleCalc::NondelegatingAddRef()
{
return InterlockedIncrement(&m_cRef) ;
}
ULONG __stdcall CSimpleCalc::NondelegatingRelease()
{
if (InterlockedDecrement(&m_cRef) == 0)
{
delete this ;
return 0 ;
}
return m_cRef ;
}