ATL中类型库的注册

 

一直不想管什么类型库之内的东西,觉得它对我的浏览器扩展工作一点
作用也没有,但是最近研究的部分又离不开它,一直可爱的vb中使用com又都是靠
它,还有可爱的.net 也用它来生成程序集的,没办法也只能学习下看。

对于非c++语言或是脚本语言都读不懂什么头文件中的信息,我们需要通过一种中立
的方式来让一般语言得到这些信息,类型库就是这样一种约定的“二进制”形式

为了使它对于一个脚本引擎读取我们类型库更容易和标准化,我们将添加一些被命名为IDispatch接口的函数给我们的对象。脚本引擎只通过这些IDispatch接口函数来获得类型库。由于脚本引擎不直接存取我们的类型库,这意味着如果微软开发一个后期版本的类型库,这些杂乱的版本细节对于脚本引擎是隐藏的。

使用IDispatch接口来读取类型库是脚本语言必须的,也是唯一的一条路了
这个接口有四个函数GetTypeInfoCount、GetTypeInfo、GetIDsOfNames和Invoke

看看这个脚本调用的过程,你就明白了

set myObj = CreateObject("IExample2.object")
myObj.SetString("Hello world")

脚本调用VB引擎的CreateObject。注意应该传入我们IExample2的ProdID。
CreateObject首先会调用CLSIDFromProgID来通过ProdID查询IExample2的GUID。
然后CreateObject调用CoCreateInstance来获得我们DLL分配的一个IExample2的指针。
脚本把它存储在myObj变量中。

接下来,脚本调用我们IExample2的SetString,
把“Hello World”字符串传入。
脚本引擎通过调用IExample2的GetIDsOfName来获得SetString的DISPID,
然后调用IExample2的Invoke,传递一个封装了“Hello World”BSTR的VARIANT来完成这个操作。

这个内部的调用过程,这里我们要实现这些需要做的就是:
需要load一个类型库,因为这样GetIDsOfName才能知道是调用哪个DISPID,有了这个才能通过
二进制的方式直接从vtable中通过位置来存取我们需要的函数指针。

但是在那里可以读到这个类型库,这个类型库的位置我们是不知道的,
怎么办,老办法,注册到注册表中,
用这个函数LoadRegTypeLib就可以从注册表中把它直接读入,有了这个类型库。可以在其中通过
Invoke调用任何方法。具体这个东西怎么写,应该蛮简单吧。其实最终的实现都是这个ITypeInfo
完成的,我们实际上什么也没有干。(有时候对这些封装的东西真的是又爱又恨)


那注册表也不是生来就有这个东西,自己随便写个类,注册表中就有,那么我真的服了windows了。
不是的,真不是这样,操作系统也不是神,要注册表中能够读到这个信息必须使用RegisterTypeLib
这个API,就是用来注册我们的类型文件的。

那么ATL做了些什么来帮助我们完成类型库的注册呢?

ATL提供了一个叫做CAtlModule的类来帮助实现著名的导出函数DllRegisterServer和DllUnregisterServer
这个类中最重要的两个函数就是RegisterServer和UnregisterServer,那么不仅可以完成类型库的调用,
同时还会调用对象映射表中每个类的UpdataRegister方法来注册每个类,这个之前已经研究过了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值