OBJECT_ENTRY_AUTO的背后(AC2)

   AC2,由VS2005的ATL向导生成的默认COM对象代码分析ATL如何实现COM,第二部分。
   OBJECT_ENTRY_AUTO相当不起眼的放在我们声明的类的头文件的最底行,但是位置不起眼作用却相当大,我给它的评价是ATL COM的基石。
  以 XXX表示我们自己的com对象类,OBJECT_ENTRY_AUTO在我们的类名和iid上扩展为(我多贴了其他#pragma):
//为了比对,贴一下_ATL_OBJMAP_ENTRY声明

struct _ATL_OBJMAP_ENTRY30 

{

	/*1*/	const CLSID* pclsid;

	/*2*/	HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister);

	/*3*/	_ATL_CREATORFUNC* pfnGetClassObject;

	/*4*/	_ATL_CREATORFUNC* pfnCreateInstance;

	/*5*/	IUnknown* pCF;

	/*6*/	DWORD dwRegister;

	/*7*/	_ATL_DESCRIPTIONFUNC* pfnGetObjectDescription;

	/*8*/	_ATL_CATMAPFUNC* pfnGetCategoryMap;



	/*9*/	void (WINAPI *pfnObjectMain)(bool bStarting);

};



typedef _ATL_OBJMAP_ENTRY30 _ATL_OBJMAP_ENTRY;



//OBJECT_ENTRY_AUTO(__uuidof(XXX), XXX)的定义,在atlcom.h中

__declspec(selectany)	_ATL_OBJMAP_ENTRY	__objMap_XXX	=	//selectany声明了现在就赋值这个__objMap_XXX,尽管在头文件中

{

	/*1*/	&clsid,

	/*2*/	XXX::UpdateRegistry,

	/*3*/	XXX::_ClassFactoryCreatorClass::CreateInstance,

	/*4*/	XXX::_CreatorClass::CreateInstance

	/*5*/	NULL,

	/*6*/	0,

	/*7*/	XXX::GetObjectDescription,

	/*8*/	XXX::GetCategoryMap,

	/*9*/	XXX::ObjectMain

};



//我把代码里的美元符号换车¥了,因为只要使用美元符号blog显示就不正常

//这里不但告诉编译器现在就赋值,而且要把该变量写入符号表保存

extern "C" __declspec(allocate("ATL¥__m")) __declspec(selectany)   _ATL_OBJMAP_ENTRY* const __pobjMap_XXX  = &__objMap_XXX;

__pragma(comment(linker, "/include:___pobjMap_XXX"));		//编译器要求保存入符号表的变量应该加_,所以加了一个



//为了方便查找,ATL在符号表里定义了另外两个ATL¥__分别做begin、end标志

//在atlbase.h中

#pragma section("ATL¥__a", read, shared)

#pragma section("ATL¥__z", read, shared)

#pragma section("ATL¥__m", read, shared)

extern "C"

{

	__declspec(selectany) __declspec(allocate("ATL¥__a")) _ATL_OBJMAP_ENTRY* __pobjMapEntryFirst = NULL;

	__declspec(selectany) __declspec(allocate("ATL¥__z")) _ATL_OBJMAP_ENTRY* __pobjMapEntryLast = NULL;

}
//当连接器布局代码时,它会根据字母排序组织段
 
 
   通过OBJECT_ENTRY_AUTO宏,dll在编译阶段定位信息得以保存,因而dll启动的时候就有了它需要的信息(只要保存了)。对于com这种在启动的时候需要和外部库有太多交互的设计,保存这些信息使得交互变为可行,不然的话,com库找不到函数,dll本身还没有初始化,就变成鸡生蛋还是蛋生鸡的问题了。再从com的二进制设计思想来看,也必须要有这样的实现,dll通过使用这种规则使得任意com对象都可以在某个二进制位置上找到特定函数(通过符号表找到符号)。

你可能感兴趣的:(ATL)