COM明明是一种编程思想,是一门绝世武功。可时代忽然迈入火器,无数人抛弃掉这晦涩难懂的绝世武功,转身投入速成的技艺时代。
“很多不懂 com 的C++程序员会自行发明一个 com 的子集,而且是蹩脚的多的子集。可惜的是,刀与剑的时代结束了,火器时代,掌握 com 这类武功已经没用了。”
---知乎网友
接口实现对象组织宏OBJECT_ENTRY_AUTO
每当我们建立一个新的ATL对象,即对应一个接口方法的实现类,但并无法找到一个继承或聚合该类的地方。
只有一个OBJECT_ENTRY_AUTO处传入其实现类和其uuid。
//OBJECT_ENTRY_AUTO(__uuidof(ExcuteATLSimpleObject), CExcuteATLSimpleObject)
//_ATL_OBJMAP_CACHE
__declspec(selectany) ATL::_ATL_OBJMAP_CACHE __objCache__CExcuteATLSimpleObject = { NULL, 0 };
//定义_ATL_OBJMAP_ENTRY_EX
const ATL::_ATL_OBJMAP_ENTRY_EX __objMap_CExcuteATLSimpleObject =
{ &__uuidof(ExcuteATLSimpleObject),
CExcuteATLSimpleObject::UpdateRegistry,
CExcuteATLSimpleObject::_ClassFactoryCreatorClass::CreateInstance,
CExcuteATLSimpleObject::_CreatorClass::CreateInstance,
&__objCache__CExcuteATLSimpleObject,
CExcuteATLSimpleObject::GetObjectDescription,
CExcuteATLSimpleObject::GetCategoryMap,
CExcuteATLSimpleObject::ObjectMain };
//指定变量定义在ATL区段
extern "C" __declspec(allocate("ATL$__m"))
__declspec(selectany) const ATL::_ATL_OBJMAP_ENTRY_EX* const
//获取地址
__pobjMap_CExcuteATLSimpleObject = &__objMap_CExcuteATLSimpleObject;
//指定 /include 选项来强制包含符号
__pragma(comment(linker, "/include:__pobjMap_CExcuteATLSimpleObject"));
全局objMap
巧妙的Section — — 剖析ATL OBJECT_MAP的自动建立
该处设置十分巧妙,保证其处于数组的前后,而在ATL中也可以看到很多使用上述两个变量遍历对象,从而达到聚合的目的。
//定义一个连续排列的区段
#pragma section("ATL$__a", read)
#pragma section("ATL$__z", read)
#pragma section("ATL$__m", read)
extern "C"
{
//amz会在区段中按顺序排列
//在ATL区段内a段定义 __pobjMapEntryFirst,保证其在前方
__declspec(selectany) __declspec(allocate("ATL$__a")) _ATL_OBJMAP_ENTRY_EX* __pobjMapEntryFirst = NULL;
//在ATL区段内z段定义一__pobjMapEntryLast 保证其在ATL区段的后方
__declspec(selectany) __declspec(allocate("ATL$__z")) _ATL_OBJMAP_ENTRY_EX* __pobjMapEntryLast = NULL;
}
//添加ATL到.rdata区段
#pragma comment(linker, "/merge:ATL=.rdata")