Microsoft 游戏开发工具包中的错误处理

Microsoft 游戏开发工具包(GDK)是基于许多新技术和现有技术构建的。 这些技术包括许多典型的 Win32 样式 API、COM API、DirectX 图形 API 等,它们已经定义了标准的错误处理方法。 因此,如何处理错误取决于具体的技术。

尽管有些 API 可能仍需要使用经典的 Win32 或 COM 错误处理,但大多数 Microsoft 游戏开发工具包 (GDK) API 都会返回 HRESULT 值。

在大多数情况下,Microsoft 游戏开发工具包 (GDK) API 被设计为“无异常”,但是游戏仍然可以选择使用 C++ 异常处理。 对于处理需要快速失败的不可恢复的错误,这通常是一个不错的选择。 继续使用“异常安全”编码样式也是一个好主意,它在代码中可以使用 C++ 异常,也可以不使用。

从 Microsoft 游戏开发工具包 (GDK) API 处理 HRESULTS

大部分 Microsoft 游戏开发工具包 (GDK) API 返回 HRESULT 值来指示 API 调用成功或失败。 您可以使用 SUCCEEDED(hr)FAILED(hr) 宏来处理成功或可恢复的错误。 针对特定错误情况的特殊处理,可以检查 HRESULT 返回值来确定如何处理错误。

注意

通常,成功由 S_OK 表示,但是另外还有一些有效的成功返回值,包括 S_FALSE。 尽管此值在现代 COM API 中并不常用,但仍建议你避免使用 hr == S_OK,而使用 SUCCEEDED(hr)

Microsoft 游戏开发工具包(GDK)在 XgameErr.h 文件中定义了一组自定义错误代码。 有关详细信息,请参阅错误代码

许多 Microsoft 游戏开发工具包(GDK)API 使用 Windows 实现库 (WIL) 来包装从内部 Win32 或 COM 调用返回的错误。 若要了解有关 WIL 如何包装错误以返回 HRESULT 的详细信息,请参阅错误处理帮助程序

处理来自 Xbox Live API 的 HRESULT

有关 Xbox Live 调用返回的可能的 HRESULTS 的列表,请参阅 Xbox Live HRESULT 错误代码

您还可以将 HRESULT 值传递到 XblGetErrorCondition,来将错误条件分组为相关错误组,然后您可以对其执行操作。 错误组在 XblErrorCondition 枚举中定义。

使用新的异步模型处理错误

Microsoft 游戏开发工具包(GDK)引入了一种新的 C 样式异步模型,如异步编程模型中所述。 在异步模型中,你通常会调用 API 对,例如 XGameUiShowTextEntryAsyncXGameUiShowTextEntryResult

提交异步任务

调用 ...Async API,将另一个线程上的函数调用排入队列。 传递到异步调用的参数之一是 XAsyncBlock 结构,此结构可以选择包含用户指定的回调函数。 此函数将在异步任务完成时被调用(如果有)。 XAsyncBlock 还可以选择指定一个特定的任务队列用于异步排队。 若要跟踪调用进度,可使用 XAsyncBlock

...Async 函数返回一个 HRESULT 代码,指示 API 能否将任务排入队列。

以下是返回自异步 API 调用的最常见的 HRESULTS

  • S_OK:指示任务已成功添加到任务队列
  • E_NO_TASK_QUEUE:指示进程任务队列已被禁用(设置为 null),并且 XAsyncBlock 没有指定任务队列

检查异步任务的进度

你可以通过传入异步 API 调用中使用的 XAsyncBlock,调用 XAsyncGetStatus 来检查异步任务的状态。 还可以传入一个可选的布尔值,该值指示 XAsyncGetStatus 是等待异步任务完成还是取消。

以下是返回自 XAsyncGetStatus 调用的最常见的 HRESULTS

  • S_OK:异步任务成功完成。
  • E_PENDING:异步任务仍在排队或正在进行中。
  • E_ABORT:异步任务已取消。
  • E_INVALIDARG:异步块无效。
  • 其他:如果异步任务失败,这表明异步任务返回了 HRESULT 错误代码。 有关可能值的列表,请查看特定的 API 文档或参阅错误代码

检查异步任务的结果

如果你在异步块中指定了回调,则可以在回调函数中通过调用匹配的 ...Result API 来检查异步调用的结果。 HRESULT 返回值应该与通过调用 XAsyncGetStatus 返回的值匹配。 如果你在回调中调用 API,则应该不会收到 E_PENDING 返回值。 但是如果你在回调之外调用 API,则应检查该返回值以确保任务未继续进行。

典型 Win32 错误处理和 COM 错误处理

对于不返回 HRESULT 值的 Win32 API,请查看文档了解返回值如何指示错误(通常是返回零)。 然后,你可以通过调用 GetLastError API 检索最新的错误代码。 请注意,你可以使用 HRESULT_FROM_WIN32 宏将典型的 Win32 错误代码转换为 HRESULT

有关 Win32 API 中的错误处理的详细信息,请参阅错误处理

有关处理 COM 错误的信息,请参阅 COM 中的错误处理