打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
OBJECT_ENTRY 映射
userphoto

2011.11.15

关注

对象映射图:

 BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_Math, CMath)
END_OBJECT_MAP()

其中OBJECT_ENTRY映射为--->

#define OBJECT_ENTRY(clsid, class) {
&clsid, class::UpdateRegistry
class::_ClassFactoryCreatorClass::CreateInstance,  ----组件类厂创建
class::_CreatorClass::CreateInstance,   ----组件实例创建
NULL, 
0, 
class::GetObjectDescription, 
class::GetCategoryMap, 
class::ObjectMain 
},

其中的_ClassFactoryCreatorClass和_CreatorClass定义如下(都为创建类--CComCreator):
#define DECLARE_CLASSFACTORY() DECLARE_CLASSFACTORY_EX(ATL::CComClassFactory)
#define DECLARE_CLASSFACTORY_EX(cf) typedef ATL::CComCreator< ATL::CComObjectCached< cf > >_ClassFactoryCreatorClass;

#define DECLARE_AGGREGATABLE(x) public:/
 typedef ATL::CComCreator2< ATL::CComCreator< ATL::CComObject< x > >, ATL::CComCreator< ATL::CComAggObject< x > > > _CreatorClass;


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;
#pragma warning(push)
#pragma warning(disable: 6014)
        
/* prefast noise VSW 489981 */
        ATLTRY(p 
= new T1(pv))
#pragma warning(pop)
        
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;
    }
};

当一个客户程序调用CoCreateInstanses时,COM将调哟DllGetClassObject。COM对DllGetClassObject
的调用最终会导致对AtlModuleGetClassObject的调用,而AtlModuleGetClassObject函数将在对象
映射图里搜索CLSID_Math条目。当函数找到它之后,AtlModuleGetClassObject将调用
&CMath::_ClassFactoryCreatorClass::CreateInstance并把&CMath::_CreatorClass::CreateInstance
作为参数传递进去。该参数被CComClassFactory里的m_pfmCreateInstance成员捕获。

CComClassFactory :

class CComClassFactory :
    
public IClassFactory,
    
public CComObjectRootEx<CComGlobalsThreadModel>
{
public:
    BEGIN_COM_MAP(CComClassFactory)
        COM_INTERFACE_ENTRY(IClassFactory)
    END_COM_MAP()

    
// This will be made virtual again for Beta 2
    /*virtual*/ ~CComClassFactory()
    {
    }
    
    
// IClassFactory
    STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj)
    {
        ATLASSUME(m_pfnCreateInstance 
!= NULL);
        HRESULT hRes 
= E_POINTER;
        
if (ppvObj != NULL)
        {
            
*ppvObj = NULL;
            
// can't ask for anything other than IUnknown when aggregating

            
if ((pUnkOuter != NULL) && !InlineIsEqualUnknown(riid))
            {
                ATLTRACE(atlTraceCOM, 
0, _T("CComClassFactory: asked for non IUnknown interface while creating an aggregated object"));
                hRes 
= CLASS_E_NOAGGREGATION;
            }
            
else
                hRes 
= m_pfnCreateInstance(pUnkOuter, riid, ppvObj);
        }
        
return hRes;
    }

    STDMETHOD(LockServer)(BOOL fLock)
    {
        
if (fLock)
            _pAtlModule
->Lock();
        
else
            _pAtlModule
->Unlock();
        
return S_OK;
    }
    
// helper
    void SetVoid(void* pv)
    {
        m_pfnCreateInstance 
= (_ATL_CREATORFUNC*)pv;
    }
    _ATL_CREATORFUNC
* m_pfnCreateInstance;
};

COM(通过CoCreateInstance)或客户程序(CoGetClassObject/CreateInstance)使用
CComClassFactory::CreateInstance来创建组件的实例。该函数实际调用m_pfmCreateInstance并把
pUnkOuter作为参数传递回去。如果pUnkOuter为空,表明客户程序没有进行集合,并且
CComCreator<CComObject<CMath>>::CreateInstance方法被使用。如果pUnkOuter不为空,那么
则表明生成了一个集合,并且使用了CComCreator<CComAggObject<CMath>>::CreateInstance方法。

CComCreator2:

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);
    }
};

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
COM聚合
COM调用过程
COM创建过程
理解Filter创建的过程
用WTL构建HTML界面的应用程序(2)
COM技术初探
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服