【问题标题】:WinAPI C++/CLR status codes to C# Win32Exception or not?WinAPI C++/CLR 状态码到 C# Win32Exception 与否?
【发布时间】:2016-04-24 08:34:07
【问题描述】:

我正在为一个小型非托管库编写VC++/CLI C# 接口。该库使用并实现了 WINAPI 方法,因此主要使用构造作为

DWORD getResult(__out LPWSTR* result);

也就是说它不返回请求的结果,而是返回一个状态码,并将请求的结果传入输出参数中。

在 C# 中,我似乎(至少)有两种编写接口的方式:

  1. 愚蠢地将其“转换”为UInt32 getResult(String^% result);
  2. 通过编写类似String^ getResult(); 的方法在托管调用的状态码非零时抛出(例如)Win32Exception 使接口更加“面向对象”(将状态码包装在其NativeErrorCode 成员中) (如这里所示:Throwing a Win32Exception

当然,在多输出函数的情况下,这不会那么简单,但假设我不关心它们。

由于我更习惯于 OOP 而不是 VC++ 编码风格,所以我更喜欢选项 2。但是,我不确定是否没有任何理由会导致这种糟糕的设计选择(或者是否存在不是第三种,甚至更好的方法)。

【问题讨论】:

  • 95% 的可能性是这应该是 String^ GetResult() 并且对于任何错误代码都是一个例外。除非可能和预期会失败,否则应将其重命名为 TryGetResult()。

标签: c# .net c++-cli interop mixed-mode


【解决方案1】:

这在很大程度上是一个见仁见智的问题——关于异常政策的讨论可以永远持续下去。

我认为您应该主要考虑您的框架的受众。如果他们已经习惯了您的非托管库,那么他们可能更喜欢“哑转译”方法。

但是,如果您的用户是典型的 C# 开发人员,那么他们会期望 #2,所以这就是我将从这里开始介绍的内容。 C# 开发人员并不关心您是否包装了本机库,而只是希望您的库的行为与其他所有 .NET 库一样。

因此,假设您选择#2,Framework Design Guidelines 书是开始思考异常设计的好地方。 MSDN 上提供了一些精简的摘录:

至于使用 Win32Exception,如果可能的话,我会避免使用它(但我说的是不知道您的错误或您正在处理的错误数量)。问题是它只为您的用户提供一个通用的 Win32 错误消息,类似于“拒绝访问”或“找不到文件”,这对 .NET 开发人员来说是不愉快的,因为它提供了最少的上下文(即,什么文件不是找到了??)。

总而言之,我会将尽可能多的错误代码转换为标准系统异常,并且,如果您有其他有用的信息可能有助于调用者的错误处理,那么将该信息提供给现有的系统异常(或创建如果必须,您自己的自定义异常类型)。仅在万不得已时才抛出 Win32Exception。

【讨论】:

  • 感谢您的回答。所以看起来第二种方式似乎没有任何隐藏的警告。我已经开始使用第二种可能性实现接口并且使用它没有问题(尽管我仍然需要考虑抛出异常时可能出现的内存管理问题)。
猜你喜欢
  • 2015-10-23
  • 2011-06-03
  • 2010-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-25
相关资源
最近更新 更多