0

エラーを処理する正しい方法は何ですか?私は次のようなコードを作成し、MSDNで見つけたすべてのエラーコードを処理しましたが、それでも、「不明」というエラーが表示されることがあります。

HRESULT hr = pwb->Navigate2(&URL, &Flag, &TargetFrameName, &PostData, &Headers);
if(FAILED(hr))
{
    std::string message("Navigate2 failed with reason: ");
    switch(hr)
    {
        // The operation was successful.
        case S_OK:
            message.append("S_OK");
            break;
        // One or more parameters are invalid.
        case E_INVALIDARG:
            message.append("E_INVALIDARG");
            break;
        // Out of memory.
        case E_OUTOFMEMORY:
            message.append("E_OUTOFMEMORY");
            break;
        // The operation failed.
        case E_FAIL:
            message.append("E_FAIL");
            break;
        case E_ACCESSDENIED:
            message.append("E_ACCESSDENIED");
            break;
        case E_POINTER:
            message.append("E_POINTER");
            break;
        case E_UNEXPECTED:
            message.append("E_UNEXPECTED");
            break;
        default:
            message.append("Unknown");
    }
}
4

2 に答える 2

1

COMエラーの処理方法にはかなりのバリエーションがあります。戦略には、特にを使用したカスケードif SUCCEEDED()または集中型機能エラー処理の使用goto on FAILED()が含まれます。MSDNにはいくつかの良い情報があります。

エラーコードの解釈に関してFormatMessage()は、多くの場合、作業が簡単になります-これはMSDNの例です(わかりやすくするために以下に含まれています)

[ソース: http: //msdn.microsoft.com/en-us/library/windows/desktop/ms687061(v = vs.85).aspx]

    #include <stdio.h>
    #include <windows.h>
    #include <tchar.h>

    void ErrorDescription(HRESULT hr) 
    { 
         if(FACILITY_WINDOWS == HRESULT_FACILITY(hr)) 
             hr = HRESULT_CODE(hr); 
         TCHAR* szErrMsg; 

         if(FormatMessage( 
           FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, 
           NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
           (LPTSTR)&szErrMsg, 0, NULL) != 0) 
         { 
             _tprintf(TEXT("%s"), szErrMsg); 
             LocalFree(szErrMsg); 
         } else 
             _tprintf( TEXT("[Could not find a description for error # %#x.]\n"), hr); 
    }

上記の呼び出しでは、フラグは、Windowsがエラーメッセージ(解放する必要があります-使用LocalFree())にメモリを割り当て、システムメッセージテーブル(FORMAT_MESSAGE_FROM_SYSTEM)でエラーメッセージを検索することを示します。場合によっては(または使用するライブラリの種類によっては)、対応するエラーの説明がシステムメッセージテーブルに表示されないことがあります。

このような場合は、エラーの説明を自分で処理するか(例で行ったように)、ライブラリのメッセージテーブルを直接ロードしようとすることができます。これを行うには、を使用して、関数のパラメーターFORMAT_MESSAGE_FROM_HMODULEとしてモジュールハンドルを指定します。lpSourceFormatMessage()

次に例を示します。

std::wstring StackExample::getLastError( HRESULT hr ) 
{
    LPWSTR lpMsgBuf;
    DWORD ret;
    std::wstring def(L"(UNKNOWN)");
    ret = FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_HMODULE,
        GetModuleHandle(TEXT("imapi2.dll")),
        hr,
        0,
        (LPWSTR) &lpMsgBuf,
        0, NULL );

    if(ret)
    {
        std::wstring last(lpMsgBuf);
        LocalFree(lpMsgBuf);
        return last;
    }
    return def;
}
于 2012-12-21T07:41:37.623 に答える
0

HRESULTエラーコードは、実際にはLONG個々の意味を持つビットのブロックでタイプされます。つまり、switchステートメント内のすべてのエラーを処理することは非現実的です。

特定のエラーコードに対して特定の処理を行う場合は、それを実行します。それ以外の場合は、通常、マクロを使用して、返された成功/失敗を確認しSUCCEEDEDますFAILED

if(FAILED(nResult))
{
  // TODO: Handle the failed operation here
}

参照:COMのエラーコード

COMメソッドが成功するかどうかを確認するには、返されたHRESULTの上位ビットを調べます。Windows SDKヘッダーは、これを容易にする2つのマクロを提供します。SUCCEEDEDマクロとFAILEDマクロです。SUCCEEDEDマクロは、HRESULTが成功コードの場合はTRUEを返し、エラーコードの場合はFALSEを返します。

于 2012-12-21T06:47:48.443 に答える