Interface 为什么AddRef()和Release()的返回类型不是HRESULT
我最近开始学习COM。在COM中,函数的返回类型应为HRESULT。已经阅读了关于Interface 为什么AddRef()和Release()的返回类型不是HRESULT,interface,com,iunknown,Interface,Com,Iunknown,我最近开始学习COM。在COM中,函数的返回类型应为HRESULT。已经阅读了关于HRESULT,GetLastError()的问题,但是为什么,IUnknown的函数,AddRef()和Release()具有返回类型ULONG 我得出的答案是,AddRef()几乎总是从QueryInterface()调用,客户端不应该调用它。对于Release(),其返回值从不检查 虽然我可以用我自己的答案来反驳- 对于AddRef(),客户端可能需要调用它。既然客户端可以访问该函数,那么如何保证客户端不会调
HRESULT
,GetLastError()
的问题,但是为什么,IUnknown的函数,AddRef()
和Release()
具有返回类型ULONG
我得出的答案是,AddRef()
几乎总是从QueryInterface()
调用,客户端不应该调用它。对于Release()
,其返回值从不检查
虽然我可以用我自己的答案来反驳-
对于AddRef()
,客户端可能需要调用它。既然客户端可以访问该函数,那么如何保证客户端不会调用它呢
对于Release()
-同样,用户可以检查其返回类型,因为他可以
请澄清
还有,它是否像-->它的约定一样为COM相关函数使用HRESULT返回类型,而不是强制-->如果这是真的,它将停止我大脑中的混乱
“AddRef和Release永远不会失败,因此拥有它们没有任何意义
返回HRESULT。“-Igor Tandetnik
我将此作为一个答案发布,只是因为我的眼睛在阅读整个问题和所有评论时流着血,希望能帮助别人。。。来吧,社区,让我们结束这类问题。帮助没有这些垃圾的人筛选会容易得多。我问自己一个类似的问题:为什么界面中需要3个方法而不是2个?QueryInterface和Release应该足够了。QI已经做了AddRef,理论上我们有两种方法来做基本相同的工作,其中一种应该被淘汰。气做它的事加上AddRef。AddRef只做AddRef。AddRef死了。接吻 对于返回类型,我不同意AddRef/Release永远不会失败的评论。嗯,他们可以。以几种不同的方式,它们应该遵循相同的HRESULT返回规则,并在参数中生成结果 AddRef失败的一个方法是,您可以超过ULONG_MAX(很难实现,但可能)。或者,用于使调用线程安全的信号量可以引发异常。事实上,很多事情都可能出错,因此我可以想象规范之所以将其设置为ULONG(void)的唯一原因是性能,因为调用一个没有参数的方法要容易得多 客户端性能早在90年代就已经是一个问题了,现在肯定不再是一个问题了(除非你说的是受限客户端,比如移动设备)。通过以性能为名牺牲语义,COM设计实际上造成了长期的维护负担,而牺牲了短期的性能增益,这一点大家都知道,也知道这一点一直在消失(摩尔定律,以相同的成本,容量每18个月翻一番) 但即便如此,AddRef也不应该如此频繁地被调用。这样做意味着您在系统的多个部分携带相同的对象,这本身就是一个糟糕设计的强烈标志
我也不同意这是一个糟糕的问题。这是一个好问题,因为它让人们思考。回答特定问题也是如此,因为人们会陷入困境。然而,让人们思考宽泛的/开放式的问题会教给他们一些技能,这些技能将首先防止他们陷入困境。
AddRef
和Release
永远不会失败,因此让他们返回HRESULT
是没有意义的。关于您的最后一个问题:方法不必返回HRESULT
(尽管如果愿意,它们可以返回);所有其他方法必须返回HRESULT
。这是因为封送层需要能够报告自己的错误(例如,如果调用跨越计算机边界且无法访问远程主机,则网络故障)AddRef
和Release
是[本地]
,不需要成功/失败状态(参见上面的Igor),返回值被重新用于指示参考计数器的有用内容。这使得这些非常常用的方法轻量级且性能高效。@IgorTandetnik感谢您的回复。尽管如此,我仍然认为客户端可能需要调用AddRef()
。例如,假设客户端具有本地接口指针,该指针将由服务器返回的有效接口指针分配。如果客户端和服务器都是两个不同的进程,那么它们的地址空间也会不同。因此,如果pIOne
是由服务器发送的,并且pIOneTemp
是本地的,那么在语句pIOneTemp=pIOne之后代码>,客户端将不得不调用pIOneTemp
上的AddRef()
,因为它位于完全不同的地址空间中。现在,为什么它不应该返回HRESULT
?@romar。但为什么这不是一致性的突破呢?如果COM要求我们编写的方法的返回类型为HRESULT
,则它自己的IUnknown方法仅不遵循规则。另请参见我上面的评论,并解释如果出现这种情况会发生什么?我从未说过客户不必调用AddRef
。你觉得我的评论哪一部分可以这样理解?如果客户端从未调用过AddRef
,那么IUnknown
接口一开始就不会提供AddRef
。但是这些与返回HRESULT
有什么关系呢?书本上有没有法律规定任何可以调用的方法都必须返回HRESULT
?