【问题标题】:Returning success codes from COM class defined in C#从 C# 中定义的 COM 类返回成功代码
【发布时间】:2015-10-15 10:59:45
【问题描述】:

当你在 C# 中定义一个 COM 类时,你通常会有这样的签名:

void Login(string user,string password)

自动 COM 互操作包装器意味着当从 C++ 调用时:

  • 抛出异常被转换为失败HRESULT
  • 什么都不返回被转换为返回S_OK

但是如果你想返回S_OK以外的成功代码呢?比如S_FALSE或者一些自定义的“成功,但是……”值?

注意:我正在用 C# 定义类,并且想知道如何控制 COM 互操作的功能。未基于 IDL 中的现有接口在 C# 中实现类。

【问题讨论】:

标签: c# c++ .net com com-interop


【解决方案1】:

HRESULT 通常是一个错误代码唯一数据。它很少用于传达成功; S_FALSE 是唯一明确定义的例外。在S_FALSE 的情况下,它通常仅在结果类型为 COM 布尔值 (VARIANT_BOOL) 并且当返回 (out) 为 VARIANT_FALSEHRESULT 映射到 S_FALSE 987654332@VARIANT_TRUE)。

维基百科还讨论了HRESULT 用于 COM 错误和 .Net/COM 边界 (from here) 的情况;

在 .NET Framework 中,从本机代码转换到托管代码时,HRESULT/IErrorInfo 错误代码会转换为 CLR 异常;从托管 COM 代码转换到本机 COM 代码时,CLR 异常会转换为 HRESULT/IErrorInfo 错误代码。

虽然不是决定性的,但它确实强化了HRESULT 通常被视为错误代码的事实。访问IErrorInfo 可能会提供更多数据,但我不确定它是否会如您所愿。

This MSDN article 确实提供了有关如何映射 COM 错误和异常的更多信息,再次支持错误代码;

COM 方法通过返回 HRESULT 来报告错误; .NET 方法通过抛出异常来报告它们。运行时处理两者之间的转换。 .NET Framework 中的每个异常类都映射到一个 HRESULT。

要支持“成功代码”,您可以使用额外的[out] 参数。如果代码超出您的控制范围,您可以编写一个精简的 COM 对象来为您映射它,然后在 .Net 对象中使用它。

或者,您可以使用PreserveSigAttribute但据我所知,它不会将错误转换为异常,因此您需要自己执行此操作(建议进行测试以验证这一点)。用 [PreserveSig] 注释方法应该可以解决问题。

【讨论】:

  • 您很好地证明了 S_FALSE 是异常情况,最好避免。我注意到这里特别指出“无法区分定期返回两个或多个不同成功代码的 COM 方法,例如 S_OK 或 S_FALSE。” msdn.microsoft.com/en-us/library/bb164625.aspx
【解决方案2】:

您必须在方法声明中使用[PreserveSig] 属性。这意味着它的字面意思,它保留了方法签名并防止类型库导出器重写它以使其与 COM 兼容。返回类型必须int,以使其与 HRESULT 兼容。

你的例子很简单:

   void Login(string user, string password);

变成:

   [PreserveSig]
   int Login(string user, string password);

当它是具有非 void 返回类型的方法时会更加复杂。然后,您必须按照类型库导出器的方式重写它。使用 ref 关键字将其作为额外参数添加。所以:

   bool Login(string user, string password);

变成:

   [PreserveSig]
   int Login(string user, string password, ref bool success);

请记住,S_FALSE 的值为 1,而不是 0。

【讨论】:

  • 现在没有对 HRESULT 的 .NET 异常进行自动编组,对吗?所以我的 C# 方法不应该在失败的情况下抛出异常,而是在整个过程中使用 C 风格的方法?如果它抛出会发生什么
猜你喜欢
  • 2019-03-24
  • 2014-10-09
  • 2012-04-16
  • 1970-01-01
  • 2012-11-06
  • 2017-01-01
  • 1970-01-01
  • 2011-02-05
  • 1970-01-01
相关资源
最近更新 更多