类厂是什么?就是一个工厂用于创建各种产品,将创建好的产品提供给外部用户使用。其实现如下:
factory.h
- #pragma once
- #include "unknwn.h"
- class CClassFactory :
- public IClassFactory
- {
- public:
- CClassFactory(void);
- virtual ~CClassFactory(void);
- public:
- // IUnknown
- STDMETHOD_(ULONG, AddRef)();
- STDMETHOD_(ULONG, Release)();
- STDMETHOD(QueryInterface)(REFIID riid, void** ppv);
- // IClassFactory
- STDMETHOD(CreateInstance)(IUnknown* pUnkOuter, REFIID riid, void** ppv);
- STDMETHOD(LockServer)(BOOL fLock);
- protected:
- ULONG m_cRef;
- };
factory.cpp
- #include "StdAfx.h"
- #include "factory.h"
- CClassFactory::CClassFactory(void)
- {
- m_cRef = 0;
- InterlockedIncrement(&g_cLock);
- }
- CClassFactory::~CClassFactory(void)
- {
- InterlockedDecrement(&g_cLock);
- }
- STDMETHODIMP_(ULONG) CClassFactory::AddRef()
- {
- return ++m_cRef;
- }
- STDMETHODIMP_(ULONG) CClassFactory::Release()
- {
- if(!--m_cRef)
- delete this;
- return m_cRef;
- }
- STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, void** ppv)
- {
- HRESULT hrRet = S_OK;
- if(IsBadWritePtr(ppv, sizeof(void*)))
- return E_POINTER;
- *ppv = NULL;
- if(IsEqualGUID(riid, IID_IUnknown))
- {
- *ppv = (IUnknown*)this;
- }else
- if(IsEqualGUID(riid, IID_IClassFactory))
- {
- *ppv = (IClassFactory*)this;
- }else
- {
- hrRet = E_NOINTERFACE;
- }
- if(S_OK == hrRet)
- ((IUnknown*) *ppv)->AddRef();
- return hrRet;
- }
- STDMETHODIMP CClassFactory::CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppv)
- {
- return E_NOINTERFACE;
- }
- STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
- {
- fLock ? InterlockedIncrement(&g_cLock) : InterlockedDecrement(&g_cLock);
- return S_OK;
- }
将类厂加入mycom中
- #include "factory.h"
- STDAPI DllGetClassObject(REFCLSID rclsid ,REFIID riid,void **ppv)
- {
- HRESULT hrRet;
- CClassFactory* pFactory = 0;
- if(!IsEqualGUID(rclsid, CLSID_MyCOM))
- return CLASS_E_CLASSNOTAVAILABLE;
- if(IsBadWritePtr(ppv, sizeof(void*)))
- return E_POINTER;
- pFactory = new CClassFactory;
- if(NULL == pFactory)
- return E_OUTOFMEMORY;
- hrRet = pFactory->QueryInterface(riid, ppv);
- if(!SUCCEEDED(hrRet))
- delete pFactory;
- return hrRet;
- }
目前我们实现的这些函数目的是让系统以为这是一个COM,我们的目的达到了,不过客户调用CoCreateInstance仍然会失败,那是因为CClassFactory::CreateInstance中我们直接返回了E_NOINTERFACE