如何判断两个COM指针是同一个对象

ATL 调用COM对象 创建完COM对象后,接下来是如何调用COM组件了。这里是在c++中的调用COM对象的方法。 创建COM对象一般有三种方法,正常创建一个对象,使用CoCreateInstance函数。若在远程系统中创建一个对象,使用CoCreateInstanceEX函数。而创建多个同一CLSID的对象时,使用CoGetClassObject函数。 1.先简单的使用CoCreateInstance函数创建一个C 阅读详情

故事起源于我移植V8到IE中的过程,在CSDN论坛上也发现不少问此问题的人,所以特地整理一篇文章来解释这个问题。

 

这个问题本来是一个非常简单的问题,COM指针也是指针,既然是指针,只要它们的值相同,就表示它们指向相同的COM对象,如果不同则表示不同对象。假设要写一个判断函数的情况下,表示成这样:

 

 

这种判断方法在绝大多数情况下正确,但仅仅是绝大多数,还有极少数情况下判断会失效,尤其在同一个对象有两个不同指针的情况下。什么情况呢?代理对象。微软的很多产品大量使用了代理对象,注意这里的代理对象不是指的COM对象的代理存根。代理对象的作用像一个沙箱,能有效隔离引用计数和其它方法访问异常,而且也能在安全访问方面做更多的控制。Office对Application对象使用了代理对象,IE对IHTMLWindow2对象使用了代理对象,还有其它一些DOM对象也使用了代理对象。

 

言归正传,一个COM对象既然可以存在一至多个代理对象,就必须提供方法来让用户判断这些COM对象是不是相同的对象(注意代理对象应该跟原始对象相同)。为此微软设计了IObjectIdentity接口,通过此接口的IsEqualObject方法来判断两个对象是否相同。下面的方法就是一个改进版。

 

 

到目前为止,上面的 is_com_equal 函数工作得非常好,几乎挑不出什么毛病。但我这人太固执,还真挑出了它的毛病。其实这个毛病是一个伪毛病,函数本身没有问题,但是当我在把V8移植到IE中的时候揪出了IE的一条虫,大概过程是这样的:有两个对象,一个是div对象,另一个是style对象,这两个风马牛不相及的对象居然被 IObjectIdentity::IsEqualObject 判断成了相同的对象,可以想见后果如何。这个问题折腾了我大概一周的时间才找到原因。这个现象其实是微软在实现对象的 IObjectIdentity 接口时写错代码了,迫不得已我只好另辟途径来绕过这个BUG,在判断它之前通过对比IDispatch对象的IID来临时解决接口比较问题。下面的代码体现了这种比较,但是通常读者使用上面的代码就足够了,除非他也遇到了同样的问题。

 

 

 

两个COM接口比较,居然用了如此多的代码和如此多的篇幅介绍,也真够BT的……

COM组件开发(一)—— 对象与接口 一.前言        在COM规范中,最基本的两个要素就是对象与接口,因为COM就是由这两者来共同实现的。COM对象在组件中是被封装起来的,客户代码只能通过接口来访问COM对象并享受其,由于客户与COM直接打交道的是COM接口,所以COM接口是COM最关键的要素。 二.COM对象          COM对象其实就类似于C++中的对象,也就是说某个类的实例,包含了一组数据和操作。在CO 阅读详情

相关推荐

创建和使用DirectX接口(并再次理解COM对象)

再次理解COM对象: 以前说:一个COM对象事实上是一个或一套实现了大量接口的C++类,这些接口用于和COM对象进行交流!!! 现在说:COM对象其实就是接口集,该接口集也就是函数指针(更准确的说是VTABLE)。 个人理解:由上一篇博客“一个可运行的COM程序”可推测,一个COM对象就是最终实现了一系列接口(如CCOM_OBJECT实现了IX、IY)的那个类产生的一个实例(和C++中一般的

假装狠牛逼 3051

C++判断两个指针指向的对象是否相同

class BaseA { public: int a; }; class BaseB { public: double b; }; class Derived : public BaseA, public BaseB { }; int main(int argc, char const *argv[]) { Derived derivd; Derived* pd = &derivd; BaseB* pb = &derivd; pr

我不是码农的博客~~~ 5400

COM组件的智能指针(深入浅出)

作者:王卫星   csdnid:wangweixing2000 职能指针其实只是为了我们开发者方便使用的东东,但是大多数据开发者总是害怕会有泄漏,以前的字符串的泄漏问题大家都应该知道了。atl7的出现应该让我们放心使用了!职能指针只是对我们的一些类型或者接口的封装,使我不用每次考虑这引用技术的问题!我们经常用到的职能指针CComPtr,IxxxxPtr,CComBSTR,CComVariant ,

wangweixing2000 6128

代码偶得——比较两个COM对象是否相同

晚上在挑灯夜战看代码时,突然发现一个很有意思的函数,这个函数用来比较两个COM对象是否是相同的对象的。乍看以为就是比较两个接口是否是相同的指针值,仔细琢磨才发现,仅仅比较接口是会被蒙骗的,因为还有COM包容和聚合的可能在里面,所以即使两个COM接口指针真的相同也不能断定是同一个对象的。下面先贴上代码,记录在这里供大家参考: template bool AreComObjectsEqual(T1

Gamebaby Rock Sun的博客 739

(多图预警)7个例子,7个视频,一堆图片助你把双指针按的牢牢的

大家好,我是袁厨。就是那个酷爱做饭自己考取了厨师资格证的程序员,文章中喜欢放动图的袁厨。今天给大家带来双指针的详细解析,大家记得打卡啊。在我们做题的时候很多题目都可以用双指针解决,所以我...

WantFlyDaCheng的博客 231

java判断两个对象是否是同一个对象

比较两个对象是否相等,主要通过equals()和hashCode() equals()方法 hashCode()方法 equals()和hashCode()在hashSet中使用 一、equals() equals()是Object中的方法,比较的对象的内存地址(如图一)。 Object源码但是也有的类重写了equals()方法,比较的内容是否相等。例如:String 、Math、Int...

记忆中空白的博客 1万+

com组件模型

一、动态链接库:动态链态库是大部分COM组件的承载对象(不要在意ocx,它同样也是dll,只不过改了一下后缀而已)。当然Exe同样也是可以的(TTS中的TextToSpeech对象就是一个例证),只不过在事实上要少得多。在Windows初期,动态链态库的出现是一场革命。它改变了Windows的一生,也为当今Windows操作系统的霸主地位打下一块坚实的基石。(关于Windows的历史问题,我一直没

§为艺术而技术§ 1298

COM对象

COM 对象QueryInterface 实现 关于 COM 接口的介绍请参考我的另一篇博文 COM 接口。 本文主要关注 COM 的实现。 QueryInterface 实现 QueryInterface 接口查询函数一般实现如下: HRESULT CCalculator::QueryInterface(const IID& iid, void **ppv) { if ( iid...

Blueware多媒体之窗 6687

cOM 指针

最近在玩 MSHTML 和 MSXML,被一堆 COM 接口搞的晕头转向。以前也玩过一些,但基本都是照抄别人的代码,也没注意到 IDispatch * 和 IDispatchPtr 有啥区别,就模糊的认为可能是同一个东东的两种写法罢……这次趁机仔细研究了一番,转载3篇 COM 智能指针的详细的介绍,以备不时之需 ATL智能指针类 ATL中包含的智能指针包括:CAutoPtr、CAu

jonfei的专栏 3032

对于COM对象使用ComPtr代替传统指针

对于COM对象来说使用传统指针比较麻烦,还要记得Release()防止内存泄漏,一不小心就会出现各种各样的问题。针对这种问题微软提供了对于COM对象的智能指针ComPtr,这里是官方文档https://github.com/Microsoft/DirectXTK/wiki/ComPtr 举个例子,原先的代码: 1 ID3D11Buffer* ...

431

COM对象和接口

        我们将详细介绍COM规范,尤其是COM对接口使用的约定,这部分内容是COM标准的核心。COM接口是建立在二进制一级的标准。COM的一些高级特性如多线程模型、分布式COM等都以此为基础。                2.1 COM对象    COM是面向对象的组件模型。COM提供给客户的是以对象形式封装起来的实体。    2.1.1 COM对象的标志--CLSID    COM组件

cl007的专栏 1852

COM原理及应用---- COM对象和接口

 1、COM对象的理解   COM对象类似于C++语言中类的概念,类的每个实例代表一个COM对象,它也包括属性(即状态)和方法(即操作),状态反映对象的存在,方法就是接口。 2、COM对象的标识-CLSID  GUID是一个128位的随机数,重复概率极低。它的值来源于两部分:空间值(网卡地址或随机数)和时间值。  获得GUID值可以使用VC++提供的工具:GUIDGen.e

armman的专栏 2599

ATL 创建COM对象

之前写了一篇原始dll的创建过程,以及直接使用LoadLibrary加载动态库。 但ATL所做的一个很重要的功能就是引入COM对象这个概念。 首先, ATL active template library为活动模板库,ATL为asp代码中提供COM对象应用。而一般使用活动模版库来创建COM组件。简单来说ATL一般作为方便快捷的COM开发工具使用。而ATL中使用的基本技术为 COM技术,C++模

四夕日 月 2938

COM组件对象模型

COMComponent Object Model)是一种标准。它的目的是实现软件的动态连接和无缝集成。 它一种软件组件技术标准:即建立动态的可重组的可无缝连接的跨语言的组件技术标准。 COM规范就是一套为组件架构设置标准的描述文档。符合COM的组件 以DLL形式或EXE形式发布。 它需实现动态连接和信息封装。 它可以以二进制形式发布。 它完全与语言无关。 它可以自由的升级替换而且不...

顺其自然~专栏 3388

Com对象的解释

⊙ 第一章 概述   COM 是什么   COM 对象与接口   COM 进程模型   COM 可重用性⊙ 第二章 COM 对象模型   全局唯一标识符 GUID   COM 对象   COM 接口   接口描述语言 IDL   IUnknown 接口   COM 对象的接口原则⊙ 第三章 COM 的实现   COM 组件注册信息   注册 COM 组件   类厂和 DllGetObject

EdisonGG的专栏 3986

COM中智能指针的用法

CComPtr用法2008-06-19 22:19COM接口指针很危险,因为使用过程中需要每一个使用者都要严格并且正确的AddRef和Release,一旦出现问题,就会造成对象不能被正常释放,或者对象被重复删除,造成程序崩溃。所以使用COM接口,必须小心翼翼才行。但是,即使所有的代码中,都正确的AddRef和Release,也不一定能保证万无一失,例如:void SomeApp( IHello *

foodvc的专栏 2872

用汇编语言访问com对象[三]

大量的细节使得Com看上去很复杂,但是使用起来却很简单。最难的部分就是理解里面的数据结构,尽管COM是语言无关的,但是他借用了很多c++的术语来描述自己。为了能使用某个对象com接口函数,你必须首先要从类厂中创建这个对象,并且让他来返回接口指针。这个过程被CoCreateInstance这个API函数完成。当你使用完接口时,要调用Release方法。一个COM对象可以看作是一个服务,调用com

晓斌的博客 1304
上一篇: 谷歌开发新图形验证码防止恶意非法注册
下一篇: 宏定义的极致发挥---让你的普通C++类轻松支持IDispatch自动化接口
jameshooo
博客等级 码龄19年 1184粉丝 23原创
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值