WinAPI C++/CLR 状态代码是否为 C# Win32Exception?

WinAPI C++/CLR status codes to C# Win32Exception or not?

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

DWORD getResult(__out LPWSTR* result);

也就是说它不是return请求的结果,而是一个statuscode,请求的结果在输出参数中传递。

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

  1. 笨拙地"transpile"它到UInt32 getResult(String^% result);
  2. 通过编写类似 String^ getResult(); 的方法使接口更 "object-oriented" 当托管调用的状态代码不为零时抛出(例如)Win32Exception(将状态代码包装在它的 NativeErrorCode 成员)(如此处所示:Throwing a Win32Exception

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

由于我更习惯于 OOP 而不是 VC++ 编码风格,所以我更喜欢选项 2。但是,我不确定是否没有理由可以呈现那个糟糕的设计选择(或者如果没有第三种甚至更好的方法)。

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

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

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

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

至于使用 Win32Exception,我会尽可能避免使用它(但我在不知道您的错误或您正在处理的错误数量的情况下这么说)。问题是它只为您的用户提供一条类似于 "Access denied" 或 "File not found" 的通用 Win32 错误消息,这对 .NET 开发人员来说是不愉快的,因为它提供了最少的上下文(即,什么文件不是'没找到??)。

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