ATL Internals 2ed复习.chapter 4.Creators

本文档详细介绍了ATL中用于实例创建的CComCreator、CComCreator2和CComFailCreator类,以及相关的Creator宏和CreateInstance方法。这些工具帮助开发者在FinalConstruct过程中避免错误,并支持standalone和aggregate两种方式。通过使用特定的Creator类和宏,可以简化并确保正确创建COM对象实例。
摘要由CSDN通过智能技术生成

由于CreateInstance过程中需要调用FinalConstruct,用户很容易忘记,所以ATL提供了Creator类,这些类提供了一个静态函数

static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv);


CComCreator

template <class T1>                                            
class CComCreator {                                            
public:                                                        
    static HRESULT WINAPI CreateInstance(void* pv, REFIID riid,
        LPVOID* ppv) {                                         
        ATLASSERT(ppv != NULL);                                
        if (ppv == NULL)                                       
            return E_POINTER;                                  
        *ppv = NULL;                                           
                                                               
        HRESULT hRes = E_OUTOFMEMORY;                          
        T1* p = NULL;                                          
        ATLTRY(p = new T1(pv))                                 
        if (p != NULL) {                                       
            p->SetVoid(pv);                                    
            p->InternalFinalConstructAddRef();                 
            hRes = p->_AtlInitialConstruct();                  
            if (SUCCEEDED(hRes))                               
                hRes = p->FinalConstruct();                    
            if (SUCCEEDED(hRes))                               
                hRes = p->_AtlFinalConstruct();                
            p->InternalFinalConstructRelease();                
            if (hRes == S_OK)                                  
                hRes = p->QueryInterface(riid, ppv);           
            if (hRes != S_OK)                                  
                delete p;                                      
        }                                                      
        return hRes;                                           
    }                                                          
};                                                             


例子:

STDMETHODIMP
CPenguinCO::CreateInstance(IUnknown* pUnkOuter, REFIID riid,
    void** ppv) {
    typedef CComCreator<
        CComPolyObject<CPenguin> > PenguinPolyCreator;
    return PenguinPolyCreator::CreateInstance(pUnkOuter,
        riid, ppv);
}


由于typedef在不同的地方可能会造成多重命名,所以一种合理的方法是:

class CPenguin : ... {
public:
    ...
    typedef CComCreator<
        CComPolyObject<CPenguin> > _CreatorClass;
};


 

STDMETHODIMP CAviary::CreatePenguin(IBird** ppbird) {
    return CPenguin::_CreatorClass::CreateInstance(0,
        IID_IBird,
        (void**)ppbird);
}


在chapter5,可以使用CComCoClass:

template <class T, const CLSID* pclsid = &CLSID_NULL>           
class CComCoClass {                                             
public:                                                         
    ...                                                         
    template <class Q>                                          
    static HRESULT CreateInstance(IUnknown* punkOuter, Q** pp) {
        return T::_CreatorClass::CreateInstance(punkOuter,      
            __uuidof(Q), (void**) pp);                          
    }                                                           
    template <class Q>                                          
    static HRESULT CreateInstance(Q** pp) {                     
        return T::_CreatorClass::CreateInstance(NULL,           
            __uuidof(Q), (void**) pp);                          
    }                                                           
};                                                              


这样,代码简化为:

class CPenguin : ...,
public CComCoClass<CPenguin, &CLSID_Penguin>, ... {...};


 

STDMETHODIMP CAviary::CreatePenguin(IBird** ppbird) {
    return CPenguin::CreateInstance(ppbird);
}


CComCreator2

这个类是为了支持standalone和aggregate 2种方式

template <class T1, class T2> class CComCreator2 {               
public:                                                          
    static HRESULT WINAPI CreateInstance(void* pv, REFIID riid,  
        LPVOID* ppv) {                                           
        ATLASSERT(*ppv == NULL);                                 
        return (pv == NULL) ? T1::CreateInstance(NULL, riid, ppv)
                            : T2::CreateInstance(pv, riid, ppv); 
    }                                                            
};                                                               


例如:

class CPenguin : ... {
public:
    ...
    typedef CComCreator2< CComCreator< CComObject<CPenguin> >,
        CComCreator< CComAggObject<CPenguin> > >
        _CreatorClass;
};


CComFailCreator

如果用户只准备实现standalone或者只准备实现aggregate,可以使用这个类来进行提示:

template <HRESULT hr> class CComFailCreator {                   
public:                                                         
    static HRESULT WINAPI CreateInstance(void*, REFIID, LPVOID*)
    { return hr; }                                              
};                                                              


只实现standalone例子:

class CPenguin : ... {
public:
    ...
    typedef CComCreator2< CComCreator< CComObject<CPenguin> >,
        CComFailCreator<CLASS_E_NOAGGREGATION> >
        _CreatorClass;
};


只实现aggregate例子:

class CPenguin : ... {
public:
    ...
    typedef CComCreator2< CComFailCreator<E_FAIL>,
        CComCreator< CComAggObject<CPenguin> > >
        _CreatorClass;
};


和Creator有关的宏

#define DECLARE_POLY_AGGREGATABLE(x) public:\      
  typedef ATL::CComCreator< \                      
  ATL::CComPolyObject< x > > _CreatorClass;        
                                                   
#define DECLARE_AGGREGATABLE(x) public: \          
  typedef ATL::CComCreator2< \                     
    ATL::CComCreator< ATL::CComObject< x > >, \    
    ATL::CComCreator< ATL::CComAggObject< x > > > \
    _CreatorClass;                                 
                                                   
#define DECLARE_NOT_AGGREGATABLE(x) public:\       
  typedef ATL::CComCreator2< \                     
    ATL::CComCreator< ATL::CComObject< x > >, \    
    ATL::CComFailCreator<CLASS_E_NOAGGREGATION> > \
    _CreatorClass;                                 
                                                   
#define DECLARE_ONLY_AGGREGATABLE(x) public:\      
  typedef ATL::CComCreator2< \                     
    ATL::CComFailCreator<E_FAIL>, \                
    ATL::CComCreator< ATL::CComAggObject< x > > > \
    _CreatorClass;                                 


上述都是为了定义_CreatorClass

例如:

class CPenguin : ... {
public:
    ...
    DECLARE_AGGREGATABLE(CPenguin)
};


Macro

Standalone

Aggregation

DECLARE_AGGREGATABLE

CComObject

CComAggObject

DECLARE_NOT_AGGREGATABLE

CComObject

DECLARE_ONLY_AGGREGATABLE

CComAggObject

DECLARE_POLY_AGGREGATABLE

CComPolyObject

CComPolyObject

 

CreateInstance

static HRESULT WINAPI                             
CComObject::CreateInstance(CComObject<Base>** pp);
                                                  
static HRESULT WINAPI                             
CComAggObject::CreateInstance(IUnknown* puo,      
    CComAggObject<contained>** pp);               
                                                  
static HRESULT WINAPI                             
CComPolyObject::CreateInstance(IUnknown* puo,     
    CComPolyObject<contained>** pp);              


这些静态函数并不使用Creator,而是按部就班的创建并且调用FinalConstruct,不同的是它们返回派生类的直接指针,例子:

STDMETHODIMP
CAviary::CreatePenguin(BSTR bstrName, long nWingspan,
    IBird** ppbird) {
    HRESULT hr;
    CComObject<CPenguin>* pPenguin = 0;
    hr = CComObject<CPenguin>::CreateInstance(&pPenguin);
    if( SUCCEEDED(hr) ) {
        pPenguin->AddRef();
        pPenguin->Init(bstrName, nWingspan);
        hr = pPenguin->QueryInterface(IID_IBird, (void**)ppbird);
        pPenguin->Release();
    }
    return hr;
}


下列代码则是错误的:

STDMETHODIMP
CAviary::CreatePenguin(BSTR bstrName, long nWingspan,
    IBird** ppbird) {
    HRESULT hr;
    hr = CPenguin::_CreatorClass::CreateInstance(0,
        IID_IBird, (void**)ppbird);
    if( SUCCEEDED(hr) ) {
        // Resist this instinct!
        CPenguin* pPenguin = (CPenguin*)(*ppbird);
        pPenguin->Init(bstrName, nWingspan);
    }
    return hr;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值