相关文章推荐
着急的毛巾  ·  PostgreSQL - ERROR: ...·  1 年前    · 
豪爽的花生  ·  python ...·  1 年前    · 
骑白马的鼠标垫  ·  Android11 ...·  1 年前    · 
满身肌肉的滑板  ·  rapidjson ...·  1 年前    · 

C++/CX 中的错误处理基于异常。 从根本上讲,Windows 运行时组件将错误报告为 HRESULT 值。 在 C++/CX 中,这些值将转换为包含 HRESULT 值的强类型异常,和可通过编程方式访问的字符串说明。 异常作为从 ref class 派生的 Platform::Exception 来实现。 Platform 命名空间为最常见的 HRESULT 值定义独特的异常类,而所有其他值都通过 Platform::COMException 类来报告。 所有异常类都有一个 Exception::HResult 字段,可用于检索原始 HRESULT。 还可以从调试器中检查用户代码的调用堆栈信息,这些信息可帮助确定异常的根源,即使产生异常的代码不是用 C++ 语言编写的,情况也不例外。

在你的 C++ 程序中,你可以引发和捕获来自 Windows 运行时操作的异常、派生自 std::exception 的异常或用户定义的类型。 仅当 Windows 运行时异常将跨越应用程序二进制接口 (ABI) 边界时(例如,当捕获你的异常的代码是使用 JavaScript 编写的时),才必须引发该异常。 当非 Windows 运行时 C++ 异常到达 ABI 边界时,该异常转换为 Platform::FailureException 异常,后者表示 E_FAIL HRESULT。 有关 ABI 的更多信息,请参见 Creating Windows Runtime Components in C++

通过使用以下两个构造函数之一可声明 Platform::Exception ,这两个构造函数采用 HRESULT 参数或者 HRESULT 参数和 Platform::String ^ 参数,该参数可跨 ABI 传递到能够处理它的任何 Windows 运行时应用。 也可以使用两个 Exception::CreateException 方法 重载之一声明异常,这两个方法重载采用 HRESULT 参数或者 HRESULT 参数和 Platform::String^ 参数。

C++/CX 支持一组表示典型 HRESULT 错误的标准异常。 每个标准异常从 Platform::COMException 派生,而 Platform::COMException 从 Platform::Exception 派生。 当跨 ABI 边界引发异常时,必须引发一个标准异常。

不能从 Platform::Exception 派生您自己的异常类型。 若要引发自定义异常,请使用用户定义的 HRESULT 构造 COMException 对象。

下表列出了标准异常。

基础 HRESULT

HResult 和 Message 属性

所有异常都有一个 HResult 属性和一个 Message 属性。 Exception::HResult 属性获取异常的基础数字 HRESULT 值。 Exception::Message 属性获取系统提供的描述异常的字符串。 在 Windows 8 中,消息仅显示在调试器中,并且是只读的。 这意味着,重新引发异常时将无法对其进行更改。 在 Windows 8.1 中,可通过编程方式访问消息字符串,并在重新引发异常时提供新的消息。 调试器中还提供了更详细的调用堆栈信息,包括异步方法调用的调用堆栈。

此示例演示如何为同步操作引发 Windows 运行时异常:

String^ Class1::MyMethod(String^ argument)
    if (argument->Length() == 0) 
        auto e = ref new Exception(-1, "I'm Zork bringing you this message from across the ABI.");
        //throw ref new InvalidArgumentException();
        throw e;
    return MyMethodInternal(argument);

下一个示例演示如何捕获该异常。

void Class2::ProcessString(String^ input)
    String^ result = nullptr;    
    auto obj = ref new Class1();
        result = obj->MyMethod(input);
    catch (/*InvalidArgument*/Exception^ e)
        // Handle the exception in a way that's appropriate 
        // for your particular scenario. Assume
        // here that this string enables graceful
        // recover-and-continue. Why not?
        result = ref new String(L"forty two");
        // You can use Exception data for logging purposes.
        Windows::Globalization::Calendar calendar;
        LogMyErrors(calendar.GetDateTime(), e->HResult, e->Message);
    // Execution continues here in both cases.
    //#include <string>
    std::wstring ws(result->Data());
    //...

若要捕捉异步操作期间引发的异常,请使用任务类并添加一个错误处理继续符。 错误处理延续将其他线程上引发的异常封送回调用线程,以便你可以在代码中一个地方处理所有潜在异常。 有关更多信息,请参见 使用 C++ 异步编程

UnhandledErrorDetected 事件

在 Windows 8.1 中,可订阅 Windows::ApplicationModel::Core::CoreApplication::UnhandledErrorDetected 静态事件,通过该事件可访问即将关闭进程的未处理的错误。 无论错误源于何处,它都作为与事件参数一起传入的 Windows::ApplicationModel::Core::UnhandledError 对象到达此处理程序。 对该对象调用 Propagate 时,它根据错误代码创建并引发相应类型的 Platform::*Exception 。 在 catch 块内,可根据需要保存用户状态,然后通过调用 throw让进程终止,或者执行其他操作让程序返回已知的状态。 下面的示例演示了基本模式:

在 app.xaml.h 中:

void OnUnhandledException(Platform::Object^ sender, Windows::ApplicationModel::Core::UnhandledErrorDetectedEventArgs^ e);

在 app.xaml.cpp 中:

// Subscribe to the event, for example in the app class constructor:
Windows::ApplicationModel::Core::CoreApplication::UnhandledErrorDetected += ref new EventHandler<UnhandledErrorDetectedEventArgs^>(this, &App::OnUnhandledException);
// Event handler implementation:
void App::OnUnhandledException(Platform::Object^ sender, Windows::ApplicationModel::Core::UnhandledErrorDetectedEventArgs^ e)
    auto err = e->UnhandledError;
    if (!err->Handled) //Propagate has not been called on it yet.
        err->Propagate();
    // Catch any specific exception types if you know how to handle them
    catch (AccessDeniedException^ ex)
        // TODO: Log error and either take action to recover
        // or else re-throw exception to continue fail-fast

C++/CX 不使用 finally 子句。

C++/CX 语言参考
命名空间参考