COM编程精彩实例--COM对象

创建一个COM对象的简单过程:
1)调用COM API接口 ::CoCreateInstance(),可以直接调用或通过一个已经包装的c++类调用。这个调用需要指定两个ID,一个是要实例化的类的ID,一个是对象所在的DLL或exe文件的ID。这里都使用惟一的ID标志,而不使用类名或者文件名,这样可以避免重名带来的混淆,有时候一个庞大的系统要先将之转化为真实的文件名。
2)因为DLL或EXE文件是用ID给出的,所以系统要先将之转化为真实的文件名。这一步是通过检查系统注册表来完成的,因为每个DLL或EXE在装入时都会在系统注册表中有记录。
3)获得了真实的文件名后,COM调用API接口LoadLibrary()装载需要的DLL,或通过远程调用API启动相应的EXE文件。
4)COM根据::CoCreateInstance()中指定的另一个参数通知DLL或EXE要实例化哪个类。在DLL或EXE创建了对象之后,::CoCreateInstance()返回该对象的指针。
5)如果这个类在本地机器的DLL中,那么它的方法调用和参数传递与类指针调用一般的DLL方法没有什么区别,
6)如果对象在EXE中创建或在其它机器上,那么调用方法时参数要经过一个序列化过程,与客户/服务器模式相似,不同的是COM自动为你做了这些工作,这个过程对程序员来说几乎是透明的。
7)消灭一个COM对象只需要将该对象的引用计数减1,来通知系统不再需要这个对象。一量对象的引用 计数降至零,COM就消灭这个对象。
8)如果 一个DLL为你的应用程序提供的所有对象都被释放了,COM就会卸载这个DLL;如果一个EXE为本地或网络上的任何应用程序提供的所有对象都被释放了,COM就停止这个EXE.
///

代理/桩子概览

①COM根据接口ID请求EXE创建所需要的类的对象
②COM将同一个接口ID映射到系统注册表中的代理/桩子DLL文件
③COM调用LoadLibrary()在客户和exe服务器两端载同一个DLL
④代理/桩子DLL用于在网络通信的过程中打包和解开参数

注意事项:
1) 如果你有一个20,000字节长的数组,要把指向这个数组的指针传递给一个COM EXE方法,你也许以为你只传递了4个字节,而实际上你传递的是整个20000字节长的数组!
首先必须将整个数组传过去,在那里再申请一个新的指针,然后在服务器端的方法中可能会修改数组中全部或部分的内容,最后还要将这个数组全部传回来。
2)忽视底层实现另一个可能造成的危害是传递未初始化的指针。因为代理/桩子程序是没有智能的,它们会将指针指向的内容序列化,即使这个指针是未定义的。
如果它认为指针指向的是一个以NULL为结束的字符串,那么有可能你机器上的一半内存中的内容都会被序列化后送出去。
3)不要在应用程序之间交换内存指针

进程空间:
在程序中出现的数据指针,指向的其实并不是内存中真正的物理地址,而是应用程序换入内存时CPU指定程序的逻辑地址。因为如果CPU给你的程序指定的是物理地址,那么当程序在内存中换入换出时就需要不停地修改程序。因此,一个指针指向的逻辑地址对于另一个应用程序来说可能毫无意义,在应用程序之间传递数据时应该直接传递数据,而不要传递指针。

术语:
一般把COM DLL称为“在进程中”
把COM EXE称为“在进程外”
把在本地系统执行的COM EXE称为“本地服务器”
把在别的系统里执行的COM EXE叫做“远程服务器”
当使用COM访问远程的COM EXE时,实际上采用的是DCOM,而不是普通的COM技术。

消灭COM对象:
1)OLE32.DLL没有跟踪每个对象的使用情况,而是由对象自己维护一个引用计数器。
2)当对象刚被创建时,引用计数器设置为1;当这个对象的指针每次被传给其他函数或应用程序时,计数都加1.
3)因此当你删除对象时,并不是真正把这个对象消灭掉,而是将对象的引用 计数减1.当引用计数为零时,COM自动消灭对象。COM也监测着这个DLL/EXE,如果某个DLL/EXE服务器创建的所有对象都被删除了,那么COM就会卸载这个DLL或终止EXE的运行。
//

①每当创建COM对象的一个指针时,对象的引用计数加1;
②每当客户端用完COM对象,对象的引用计数减1;
③当引用计数减到0时,COM卸载DLL或终止EXE;
④COM的EXE服务器自动检测客户端是否仍激活着,如客户端的应用程序已死锁,则自动将引用计数减1。
一个IDL文件样本:
/

早绑定和晚绑定:
//
a)早绑定
b)晚绑定
①客户程序通过VTBL快速调用COM服务器的方法;
②客户程序直接调用IDispatch的方法;
③客户程序调用IDispatch来查看COM服务器支持什么方法需要哪些参数;
④然后客户指定一个方法的ID,告诉IDispatch要调用哪个方法



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小蚂蚁_CrkRes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值