ATL中的宏
来源:互联网 发布:锋芒网络剧百度云 编辑:程序博客网 时间:2024/05/21 15:38
#define BEGIN_OBJECT_MAP(x) static _ATL_OBJMAP_ENTRY x[]= {
#define OBJECT_ENTRY(clsid, class ) { &clisd, class::UddateRegistry, /
class::_ClassFactoryCreatorClass::CreateInstance /
class::_CreatorClass::CreateInstace, /
NULL, 0 , class::GetObjectDescription, /
class::GetCategoryMap, class::ObjectMain },
#define END_OBJECT_MAP() { NULL, NULL, NULL,NULL,NULL,NULL,NULL,NULL}};
如:
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_IXXX, CIXXX)
END_OBJECT_MAP( )
_ATL_OBJMAP_ENTRY结构示意
pclsid
pfnUpdateRegistry 注册和注销类函数
pfnGetClassObject 类厂创建函数
pfnCreateInstance 类实例创建函数
pCF
dwRegister
pfnGetObjectDescription
pfnGetCategoryMap
pfnObjectMain
#define DECLARE_CLASSFACORY()
DELARE_CLASSFACTORY_EX(CComClassFactory)
对于进程内服务器为下面定义
#define DECLARE_CLASSFACTORY_EX(cf)
typedef CComCreator< CComObjectCached< cf > > _ClassFactoryCreatorClass;
#define DECLARE_AGGREGATABLE(x) public:/
typedef CComCreator2< CComCreator< CComObject< x > >, CComCreator< CComAggObject< x > > > _CreatorClass;
这宏说明在类CComCoClass中
有如下成员: _ClassFactoryCreatorClass
_CreatorClass
注意到:
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);
}
};
我们将创建一个实例并且在整个服务器生命周期内拥有它,一旦被除数请求就提交它的引用
template <class Base>
class CComObjectCached : public Base
{
public:
typedef Base _BaseClass;
CComObjectCached(void* = NULL){}
STDMETHOD_(ULONG, AddRef)()
{
m_csCached.Lock();
ULONG l = InternalAddRef();
if (m_dwRef == 2)
_Module.Lock();
m_csCached.Unlock();
return l;
}
STDMETHOD_(ULONG, Release)()
{
m_csCached.Lock();
InternalRelease();
ULONG l = m_dwRef;
m_csCached.Unlock();
if (l == 0)
delete this;
else if (l == 1)
_Module.Unlock();
return l;
}
//_InternalQueryInterface这一个函数在宏中定义了
STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject)
{return _InternalQueryInterface(iid, ppvObject);}
CComGlobalsThreadModel::AutoCriticalSection m_csCached;
};
所有类的基类,实现了IUnknown的行为,还有聚合等行为
class CComObjectRootBase
{
public:
CComObjectRootBase()
{
m_dwRef = 0L;
}
HRESULT FinalConstruct()
{
return S_OK;
}
HRESULT _AtlFinalConstruct()
{
return S_OK;
}
void FinalRelease() {}
void _AtlFinalRelease() {}
static void WINAPI ObjectMain(bool /* bStarting */) {}
static HRESULT WINAPI InternalQueryInterface(void* pThis,
const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject)
{
//使用了全局函数和全局变量_Module中的函数
}
ULONG OuterAddRef()
{
return m_pOuterUnknown->AddRef();
}
ULONG OuterRelease()
{
return m_pOuterUnknown->Release();
}
HRESULT OuterQueryInterface(REFIID iid, void ** ppvObject)
{
return m_pOuterUnknown->QueryInterface(iid, ppvObject);
}
void SetVoid(void*) {}
void InternalFinalConstructAddRef() {}
void InternalFinalConstructRelease()
{
ATLASSERT(m_dwRef == 0);
}
union
{
long m_dwRef;
IUnknown* m_pOuterUnknown;
};
};
当创建者创建一个类厂实例会调用SetVoid方法,给函数指针赋值,这个指针用于创建一个类的实例.
1. 首先COM库的调用,链接到导出函数DllGetClassObject
2. 调用全局变量的GetClassObject,这个函数调用全局函数AtlModuleGetClassObject, 在这个函数中有一句
3. pEntry->pfnGetClassObject(pEntry->pfnCreateInstance, IID_IUnknown, (LPVOID*)&pEntry->pCF)
4. 把这个指针pEntry->pfnCreateInstance传递进去
5. 查看对象映射表得知pfnGetClassObjectr 的值为
6. class::_ClassFactoryCreatorClass::CreateInstance
7. 即为 CComCreator< CComObjectCached< CComClassFactory > > ::CreateInstance
8. 下面来看看CreateInstance函数的实现,大致过程是这样:
{
CComObjectCached < CComClassFactory > * p = NULL;
P = new CComObjectCached < CComClassFactory >(pEntry->pfnCreateInstance) //构造函数空
执行SetVoid(…)
p->SetVoid(pEntry->pfnCreateInstance)
}
9. 执行其父类的SetVoid函数,即为CComClassFactory,其代码为:
void SetVoid(void* pv)
{
m_pfnCreateInstance = (_ATL_CREATORFUNC*)pv;
}
10. 在内部使用类厂的指针调用如下代码
pIFactory->CreateInstance(…………….),其执行为
hRes = m_pfnCreateInstance(pUnkOuter, riid, ppvObj);
11. pfnCreateInstance 所指向的函数为
CComCreator2< CComCreator< CComObject< T > >, CComCreator< CComAggObject< T > > > ::CreateInstance 其函数实现为:
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);
}
12. 下面来看看CComCoClass的定义
template <class T, const CLSID* pclsid = &CLSID_NULL>
class CComCoClass
{
public:
DECLARE_CLASSFACTORY()
展开为: 实质上为一个CComCreator的一个成员
typedef CComCreator< CComObjectCached < CComClassFactory > > _ClassFactoryCreatorClass;
DECLARE_AGGREGATABLE(T)
展开为: 实质上为一个CComCreator2的一个成员
typedef CComCreator2< CComCreator< CComObject< T > >, CComCreator< CComAggObject< T > > > _CreatorClass;
typedef T _CoClass;
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);
}
};
template <class T1>
class CComCreator //T1是一个类,在调用了这个类的很多方法
{
public:
static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv)
{
ATLASSERT(*ppv == NULL);
HRESULT hRes = E_OUTOFMEMORY;
T1* p = NULL;
ATLTRY(p = new T1(pv))
if (p != NULL)
{
p->SetVoid(pv);
p->InternalFinalConstructAddRef();
hRes = p->FinalConstruct();
p->InternalFinalConstructRelease();
if (hRes == S_OK)
hRes = p->QueryInterface(riid, ppv);
if (hRes != S_OK)
delete p;
}
return hRes;
}
};
类厂的实现
class CComClassFactory :
public IClassFactory,
public CComObjectRootEx<CComGlobalsThreadModel>
{
public:
BEGIN_COM_MAP(CComClassFactory)
COM_INTERFACE_ENTRY(IClassFactory)
END_COM_MAP()
STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj)
{
ATLASSERT(m_pfnCreateInstance != NULL);
HRESULT hRes = E_POINTER;
if (ppvObj != NULL)
{
*ppvObj = NULL;
if ((pUnkOuter != NULL) && !InlineIsEqualUnknown(riid))
{
hRes = CLASS_E_NOAGGREGATION;
}
else
hRes = m_pfnCreateInstance(pUnkOuter, riid, ppvObj);
}
return hRes;
}
STDMETHOD(LockServer)(BOOL fLock)
{
if (fLock)
_Module.Lock();
else
_Module.Unlock();
return S_OK;
}
void SetVoid(void* pv)
{
m_pfnCreateInstance = (_ATL_CREATORFUNC*)pv;
}
_ATL_CREATORFUNC* m_pfnCreateInstance;
};
- ATL中的宏
- ATL中的宏
- 关于ATL中的字符转换宏
- ATL中的聚合
- ATL中的字符串
- ATL 中的ActiveX 容器
- ATL中的rgs文件
- ATL中的集合和枚举
- 理解ATL中的关键点
- ATL中的Thunk机制学习
- ATL中的RGS文件介绍
- Visual Studio 2008 中的 ATL
- ATL中的创建对象模型
- ATL中的RGS文件介绍
- ATL与MFC中的CString
- ATL COM中的Type Library
- ATL中的RGS文件介绍
- c++ATL中的checkbox控件
- Windows Mobile 开发相关资源地址
- 微软实习生要求
- C语言已经死了,5个需要忘却的理由
- 用VNC实现远程桌面共享(支持Windows, Linux, ...)
- 《深入解析ATL》笔记(二)
- ATL中的宏
- 有关 Windows Mobile 5.0 模拟器的网络配置
- ubuntu 快速更新
- 文章标题: 在右键中添加自定义菜单
- 遍历指定文件夹下所有的xml文件并动态生成HTML页面!
- 感悟
- 如何优化C语言代码(程序员必读)
- 质量管理新理念——以员工为中心
- 回来了