【发布时间】:2023-03-19 13:34:01
【问题描述】:
最近开始学习COM。在 COM 中,函数的返回类型应该是 HRESULT。读过HRESULT,GetLastError() 的问题,但是为什么,IUnknown 的函数AddRef() 和Release() 有返回类型ULONG?
我想出的答案是AddRef()(几乎)总是从QueryInterface() 调用,并且客户端不应该调用它。而对于Release(),它的返回值永远不会被检查。
虽然我可以用我自己的答案来争论——
对于AddRef() - 客户可能会遇到必须打电话给它的情况。并且由于客户端可以访问该函数,客户端不会调用它的保证是什么。
对于Release() - 同样,用户可以检查其返回类型,因为他可以
请澄清。
也像 --> 它的约定是为 COM 相关函数设置 HRESULT 返回类型,而不是强制 --> 如果这是真的,它将停止我大脑中的混乱。
【问题讨论】:
-
AddRef和Release永远不会失败,所以让他们返回HRESULT毫无意义。关于你的最后一个问题:[local]方法不必返回HRESULT(尽管如果他们愿意,他们可以);所有其他方法必须返回HRESULT。这是因为封送层需要能够报告自己的错误(例如,网络故障,如果调用跨越机器边界并且远程主机无法访问)。AddRef和Release是[local] -
不需要成功/失败状态(参见上面的 Igor),返回值被重用于指示引用计数器的有用的东西。这使得这些非常常用的方法变得轻巧且性能高效。
-
@IgorTandetnik 感谢您的回复。不过,我仍然认为客户可能需要致电
AddRef()。例如假设客户端有本地接口指针,它将由服务器返回的有效接口指针分配。如果客户端和服务器都是两个不同的进程,它们的地址空间也会不同。因此,如果pIOne是由服务器发送的,而pIOneTemp是本地的,那么在声明pIOneTemp = pIOne;之后,客户端将不得不在pIOneTemp上调用AddRef(),因为它位于完全不同的地址空间中。现在为什么它不应该返回HRESULT? -
@RomanR。但是,为什么这不是统一性的突破呢?如果 COM 要求我们编写的方法返回类型为
HRESULT,那么只有它自己的 IUnknown 的方法不符合规则。另请参阅我上面的评论,如果出现这种情况,请解释一下怎么办? -
我从未争辩说客户不必致电
AddRef。你觉得我评论的哪一部分可以这样解释?如果客户端永远不必调用AddRef,那么IUnknown接口首先就不会提供AddRef。但这与返回HRESULT有什么关系?书上是否有规定任何可以调用的方法都必须返回HRESULT?