【Windowsコアプログラミング】Windowsコアプログラミング--エラー処理

4061 ワード

一、一般的なWindows関数の戻り値タイプ1)VOID:この関数は失敗することはできません.ごく少数のWindows関数の戻り値タイプはVOIDです.                       VOID ExitProcess(UINT uExitCode);2)BOOL:関数が失敗した場合、戻り値は0;それ以外の場合、戻り値は0以外の値です.戻り値がTRUEであるかどうかのテストは避け、FALSEでないかどうかを確認する必要があります.                      BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode); 
なぜif(result==TRUE)を使用できず、if(result!=FALSE)を使用するのか.逆アセンブリコードの効率や命令長から何の違いもありません.
しかし、主に0、1の判断で、0は単独個体であるが、1は0でないと理解する必要があるが、機械は1と比較するだけなので、範囲を狭めた.
3)HANDLE:関数が失敗した場合、戻り値は通常NULLである.そうでない場合、HANDLEは操作可能なオブジェクトを識別します.でも失敗したときに返される値はINVALID_HANDLE_VALUE、-1と定義されています.                         HANDLE    OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId); 
4)PVOID:関数呼び出しに失敗した場合、戻り値はNULL;そうでない場合、PVOIDはデータブロックのメモリアドレスを識別します.
       5)LPVOID    HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes); 
6)LONG/DWORD:具体的なLONG/DWORD値を返し、MSDNの提示により正確に判断する必要がある.
       7)DWORD GetCurrentProcessId(VOID); 
二、関数エラーリターンコードWindows関数がエラーを検出した場合、「スレッドローカルストレージ領域」というメカニズムを使用して、対応するエラーコードを呼び出しスレッドに関連付け、異なるスレッドのエラーコードが互いに干渉しないようにします.
          GetLastError()
この関数の役割は簡単で、前の関数呼び出しで設定されたスレッドの32転位エラーを返すことです.WinError.hヘッダファイルにはMiscrSoft定義のエラーコードリストが含まれています.
Windows関数の呼び出しに失敗した後、すぐにその関数を呼び出す必要があります.そうしないと、別のWindows関数が呼び出された後、LastErrorが書き換えられる可能性があります(Windows関数の呼び出しが成功した後、この値がERROR_SUCCESSに書き換えられる可能性があります).GetLastError()を使用するには、後続のプログラミング時にプログラムのフォールトトレランス、丈夫性をできるだけ向上させる2つの方法を見たことがあります.
コード1:
if (!WriteFile(hFile, lpBuffer, strlen(lpBuffer), &dwWritten, NULL))
{
                 return   GetLastError( );
 }       

コード2:
switch (GetLastError())
{
case ERROR_IO_PENDING:
    //...
    break;
case ERROR_PIPE_CONNECTED:
    //...
    break;
default:
    {
        printf("Connent Namepipe failed with %d.
", GetLastError()); return 0; } }

コード3:
      if(ERROR_INSUFFICIENT_BUFFER == GetLastError())
    {
           lpDeviceInterfaceDetailData = HeapReAlloc(
                             GetProcessHeap(), 0, 
                            lpDeviceInterfaceDetailData, dwBufferSize);
        
           lpDeviceInterfaceDetailData->cbSize 
                           = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
    }  

三、自分のエラーコードを定義する
1)自分で書いた関数についてもAPIでエラー番号を設定することで頑丈性を高めることができ,SetLastError()を用いることでエラー番号を修正することができるが,共通のためにエラーコードの設定にはなるべくWinErrorを用いる.hの中の.自分で新しいエラー番号を設定することもできます.
        VOID  SetLastError(DWORD   dwErrCode)
32ビットエラーコード
四、VSのデバッグ情報VSのWatchウィンドウに$errを追加すると、hrは関数エラー戻りコードと関連するプロンプト文を表示することができ、エラーメッセージが表示されます.VC 6はサポートされていません.五,ErrorShowプログラム
FormatMessage()/GetLastErrorで得られたエラー情報(このエラー情報は数値番号)を文字列情報に変換する関数
1)関数のプロトタイプ:
DWORD WINAPI FormatMessage(_in DWORD dwFlags,//フラグビットは、lpSourceパラメータ__in_opt LPCVOID lpSource,_in DWORD dwMessageId,//要求されたメッセージの識別子をどのように説明するかを決定する.dwFlagsフラグがFORMAT_MESSAGE_FROM_STRINGの場合、__inDWORD dwLanguageId,//要求されたメッセージの言語識別子__outLPTSTR lpBuffer,//キャッシュ領域にフォーマットメッセージが保存され、lpBuffer指向ヘッダアドレス_in DWORD nSize,//FORMAT_MESSAGE_ALLOCATE_BUFFERフラグは指定されていません.このパラメータは出力バッファのサイズ__に指定する必要があります.in_opt va_list*Arguments//フォーマット情報の挿入値の配列を保存します.  );
戻り値:
関数呼び出しに成功した場合は、最後の空の文字を除いて、出力バッファのサイズを返します.失敗した側は0を返します.
2)コード例:
#include <stdio.h>
#include <windows.h>
int main()
{
    DWORD dwError = 0;
    printf(" :");
    scanf("%d", &dwError);

    HLOCAL hLocal = NULL;
    DWORD SystemLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
    BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
                             NULL,
							 dwError,   // 
							 SystemLocale,  // 
							 (PTSTR)&hLocal, // , lpBuffer 。
							 0,
							 NULL);
	if(hLocal!=NULL)
	{
		MessageBox(NULL,(PCTSTR)LocalLock(hLocal),L"Title( )",MB_OK);
       // LocalLock(hLocal);
	}
    printf(" : 
"); getchar(); return -1; }