4

最近开始学习COM。在 COM 中,函数的返回类型应该是 HRESULT。已阅读有关IUnknown 函数的HRESULT问题GetLastError(),但为什么,AddRef()Release()有返回类型ULONG

我想出了AddRef()(几乎)总是从 调用的答案QueryInterface(),而客户不应该调用它。而对于Release(),它的返回值永远不会被检查。

虽然我可以与 - 因为AddRef()- 客户可能会遇到他不得不称之为的情况来争论我自己的答案。并且由于客户可以访问该功能,客户不会调用它的保证是什么。

for Release()- 同样,用户可以检查它的返回类型,因为他可以

请说清楚。

也像 --> 它的约定是为 COM 相关函数设置 HRESULT 返回类型,而不是强制 --> 如果这是真的,它将停止我大脑中的混乱。

4

2 回答 2

0

“AddRef 和 Release 永远不会失败,所以让它们返回 HRESULT 是没有意义的。” ——伊戈尔·坦德尼克

我将其发布为答案只是因为我的眼睛因阅读整个问题和所有评论而流血,希望能帮助某人……来到 SO 社区,让这些类型的问题结束。在没有所有这些垃圾的情况下帮助人们会容易得多。

于 2014-08-27T02:45:23.863 回答
0

我问自己一个类似的问题:为什么我们在接口中需要 3 个方法而不是 2 个?QueryInterface 和 Release 应该足够了。QI 已经做了 AddRef,理论上我们有 2 种方法用于完成基本相同的工作,其中一种应该被淘汰。QI 做它的事情加上 AddRef。AddRef 只做 AddRef。AddRef 死了。吻。

现在对于返回类型,我不同意 AddRef/Release 永远不会失败的评论。嗯,他们可以。在几种不同的方式中,它们应该遵循相同的 HRESULT 返回和结果参数规则。

AddRef 可能失败的一种方法是您可以超过 ULONG_MAX(几乎无法实现,但可能)。或者用于使该调用线程安全的信号量可能会引发异常。很多事情实际上都可能出错,以至于我可以想象规范将其简单地称为 ULONG(void) 的唯一原因是性能,因为调用没有参数的方法要容易得多。

客户端性能早在 90 年代就已经是一回事了,现在绝对不再是一回事了(除非您谈论的是受限客户端,例如移动设备)。通过以性能的名义牺牲语义,COM 设计实际上造成了长期的维护负担,而牺牲了每个人都知道并且总是消失的短期性能提升(摩尔定律,容量每 18 倍月以相同的成本)。

但即便如此,您也不应该如此频繁地调用 AddRef。这样做意味着您在系统的多个部分携带相同的对象,这本身就是一个糟糕设计的有力指标。

我也不同意这是一个糟糕的问题。这是一个很好的问题,因为它让人们思考。SO 是关于回答具体问题,因为人们被卡住了。然而,让人们思考广泛/开放式的问题会教给他们技能,以防止他们一开始就陷入困境。

于 2018-04-12T22:22:52.530 回答