COM中错误代码的礼仪

时间:2014-05-06 09:43:06

标签: com

在COM对象中,通常有两种方式指示函数失败(我意识到):

  • 返回S_OK并拥有[out]参数以提供失败信息
  • 返回失败HRESULT,并使用ICreateErrorInfo设置信息。

目前我正在做的是使用失败 - HRESULT方法来处理非常糟糕的故障",即我的对象基本上无法操作,因为此功能失败了。例如,无法打开其配置文件。

这是正确的,还是只应该为调度参数类型不匹配等事项保留HRESULT失败?

1 个答案:

答案 0 :(得分:1)

简短版本:

在COM中,您应该使用HRESULT(并努力使用ISupportErrorInfo等)来处理大多数/所有类型的错误情况。应将HRESULT机制视为异常抛出的一种形式。如果您熟悉它,请将“错误条件”视为通常在支持它们的语言中引发异常的任何内容。对于通常不会使用例外情况的事物,请使用自定义返回值。

例如,对无效参数,无效操作序列,网络故障,数据库错误,内存不足等意外情况等使用故障HRESULT。另一方面,使用自定义输出参数,例如'轮询,数据还没有准备好',EOF条件,也许'检查数据并且它没有通过验证'。有很多讨论讨论每个应该是什么(例如Stroustrup的TC++PL)。具体细节将在很大程度上取决于您的特定对象的语义。

版本较长:

从根本上讲,COM HRESULT机制只是一种错误代码机制,已由基础架构标准化。这主要是因为COM必须支持许多功能,如进程间(DCOM)和线程间(公寓)执行,系统管理服务(COM +)等。基础结构需要知道何时

每种语言和程序员都可以选择如何呈现或处理这些错误。在C ++中,我们通常将HRESULT作为错误代码处理(尽管如果您喜欢以这种方式进行错误处理,可以将它们转换为异常)。在.NET语言中,故障HRESULT被转换为异常,因为这是.NET中首选的错误机制。

VB6支持“或者”。现在,我知道VB6的所谓异常处理有一个痛苦的语法和处理程序的有限范围选项,但如果你不想,你不必使用它。如果您认为在特定情况下使用模式证明它是合理的,您可以随时使用ON ERROR RESUME NEXT并手动执行。只是而不是写这样的东西:

statusCode = obj.DoSomething(param1)
If IS_FAILURE(statusCode) Then
    'handle error
End If

你这样写:

ON ERROR RESUME NEXT
...
obj.DoSomething param1
IF Error.Number <> 0 Then
    'handle error
End If

VB6只是隐藏方法调用中的错误代码返回值(并允许对象的程序员通过[retval]将其替换为“虚拟返回值”)。

如果您构建自己的错误报告机制而不是使用HRESULT,则您将:

  1. 花费大量时间重新创建一个丰富的错误报告机制,该机制可能会反映ISupportsErrorInfo已经为您提供的内容(或者很可能不会提供任何丰富的错误信息)。
  2. 隐藏COM基础架构中的错误状态(可能或可能不重要)。
  3. 强制您的VB6客户端从他们拥有的两个选项中做出一个特定的选择:他们必须进行明确的逐行检查,或者更可能只是错误地忽略错误条件,即使他们更喜欢错误处理程序
  4. 强制你的(说)C#客户端以与语言的自然风格相反的方式处理你的错误(必须明确地检查每个方法调用并且......可能会手动抛出异常)。