服务器端的 com创建(二)

本文深入解析COM组件模型的实现机制,重点介绍了ATL如何帮助开发者简化COM编程过程,包括DllGetClassObject函数的作用及其实现原理,对象映射表的构建方式及其在COM中的关键作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

昨天心情不好写太少了,今天在补一段
究竟注册了些什么,当时认识在InprocServer中写上dll路径啊
有了这个在调用CoGetClassObject的时候会加载这个dll,有了这个dll
就有了DllGetClassObject

这个是com的简单流程,也是com执行的秘密
但ATL做了什么,它帮我们写了这个DLLGetClassObject

在ATL中有这个ATLComModuleGetClassObject的函数来完成DllGetClassObject
的工作
在这个函数里面会扫描我昨天说的那个对象映射表,就是那一堆连续的_ATL_OBJMAP_ENTRY
结构,从这个结构里面获取一个pfnGetClassObject函数,有了这个函数就可以生成对应GUID
的类厂了,有了类厂你知道怎么做了吧?

这个对象表中在这个函数调过之后把这个类厂放入pCF中(就是缓存了类厂)
你直接使用CAtlModuleT类的GetClassObject来取类厂的时候取的实际就是这个类厂。

很明显,从这个可以看出,类厂永远是单实例的,而真正的对象就是这个类厂产生的,
呵呵,好像.net中我写数据库的时候写的DataProvider,单例模式+工厂模式

由于c++没有静态的构造函数,而com简单的模拟了这个操作,
_ATL_OBJMAP_ENTRY中有个ObjectMain函数,这个函数将在dll加载的时候被初始化,就是程序会
自动调用所有对象表中的所有的ObjectMain,而且永远只调用一次,这就实现了类级的初始化,
和静态构造函数是一样的。

说来说去,关键是这个对象映射表
#define OBJECT_ENTRY_AUTO(clsid, class) /
 __declspec(selectany) ATL::_ATL_OBJMAP_ENTRY __objMap_##class = {&clsid, class::UpdateRegistry, class::_ClassFactoryCreatorClass::CreateInstance, class::_CreatorClass::CreateInstance, NULL, 0, class::GetObjectDescription, class::GetCategoryMap, class::ObjectMain }; /
 extern "C" __declspec(allocate("ATL$__m")) __declspec(selectany) ATL::_ATL_OBJMAP_ENTRY* const __pobjMap_##class = &__objMap_##class; /
 OBJECT_ENTRY_PRAGMA(class)

简单的看看这个宏,里面放入了:自己的对象生成函数,自己类厂的生成函数,注册函数,
ObjectMain,当然有clsid,GetCategoryMap也是个注册时候用的函数,它将用来注册对象类别

同时在程序中一定会有很多对象,但它并不对外公开,它通常会被公开的对象构造,在ATL中它叫
做不可创建对象。
它也有个相对应的宏,
#define OBJECT_ENTRY_NON_CREATEABLE_EX_AUTO(clsid, class) /
 __declspec(selectany) ATL::_ATL_OBJMAP_ENTRY __objMap_##class = {&clsid, class::UpdateRegistry, NULL, NULL, NULL, 0, NULL, class::GetCategoryMap, class::ObjectMain }; /
 extern "C" __declspec(allocate("ATL$__m")) __declspec(selectany) ATL::_ATL_OBJMAP_ENTRY* const __pobjMap_##class = &__objMap_##class; /
 OBJECT_ENTRY_PRAGMA(class)

简单看一下,这个宏和上面的宏不同之前就在于,它没有类厂生成函数和对象生成函数,这个就
表示它一定不会被创建,至少不会由com那套逻辑来创建。

那么既然说了这个表就不能不提这个表的使用,这个可能是ATL比较得意的地方
没有对象都会创建这个结构,这些结构将注册一个表,但这些一定要放在一起才能算是一个表

可是明显,它们是一个一个创建的,在内存中它们理应离散的放置
但主要这个宏的后面几行
__declspec(allocate("ATL$__m"))在ATL$__m段中放了这个结构,这样就使得这个结构在表中是在
这个数据段中连续。

就说这么多吧,上班了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值