Share via


_CrtSetReportHook2, _CrtSetReportHookW2

將用戶端定義的報告函式連結到 C 執行階段偵錯報告處理序,以進行安裝或解除安裝 (僅限偵錯版本)。

語法

int _CrtSetReportHook2(
   int mode,
   _CRT_REPORT_HOOK pfnNewHook
);
int _CrtSetReportHookW2(
   int mode,
   _CRT_REPORT_HOOKW pfnNewHook
);

參數

mode
要採取的動作:_CRT_RPTHOOK_INSTALL_CRT_RPTHOOK_REMOVE

pfnNewHook
報告攔截,以安裝或移除此函式的窄字元或寬字元版本。

傳回值

如果發現錯誤,則為 -1,並會設定 EINVALENOMEM;否則會在呼叫後傳回 pfnNewHook 的參考計數。

備註

_CrtSetReportHook2_CrtSetReportHookW2 可讓您攔截或取消攔截函式,而 _CrtSetReportHook 只可讓您連結函式。

在 DLL 中進行攔截呼叫,且可能會有多個 DLL 載入並設定自己的攔截函式時,應使用 _CrtSetReportHook2_CrtSetReportHookW2,而不是 _CrtSetReportHook。 在此情況下,可依載入 DLL 時的不同順序來卸載 DLL,並可保留攔截函式以指向未卸載的 DLL。 如果使用 _CrtSetReportHook 新增攔截函式,任何偵錯輸出都會損毀處理序。

如果沒有使用 _CrtSetReportHook2_CrtSetReportHookW2 新增的攔截函式,或如果使用 _CrtSetReportHook2_CrtSetReportHookW2 新增的所有攔截函式都傳回 FALSE,則會呼叫使用 _CrtSetReportHook 新增的任何攔截函式。

此函式有寬字元版本可用。 報表攔截函式採用的字串類型 (寬或窄字元) 必須符合此函式所使用的版本。 針對此函式的寬字元版本搭配使用的報表攔截程序,使用下列函式原型:

int YourReportHook( int reportType, wchar_t *message, int *returnValue );

針對窄字元報表攔截程序,使用下列原型:

int YourReportHook( int reportType, char *message, int *returnValue );

這些函式會驗證它們的參數。 如果 modepfnNewHook 無效,這些函式會叫用不正確參數處理常式,如參數驗證 中所述 。 如果允許繼續執行,這些函式會將 errno 設定為 EINVAL ,並傳回 -1。

注意

如果您的應用程式是以 /clr 編譯,並在應用程式結束 main 之後呼叫報告函式,則如果報告函式呼叫任何 CRT 函式,CLR 將會擲回例外狀況。

需求

常式 必要的標頭 選擇性標頭
_CrtSetReportHook2 <crtdbg.h> <errno.h>
_CrtSetReportHookW2 <crtdbg.h> <errno.h>

如需相容性詳細資訊,請參閱相容性

程式庫

僅限偵錯版本的 C 執行階段程式庫

範例

// crt_setreporthook2.c
#include <windows.h>
#include <stdio.h>
#include <crtdbg.h>
#include <assert.h>

int __cdecl TestHook1(int nReportType, char* szMsg, int* pnRet)
{
   int nRet = FALSE;

   printf("CRT report hook 1.\n");
   printf("CRT report type is \"");
   switch (nReportType)
   {
      case _CRT_ASSERT:
      {
         printf("_CRT_ASSERT");
         // nRet = TRUE;   // Always stop for this type of report
         break;
      }

      case _CRT_WARN:
      {
         printf("_CRT_WARN");
         break;
      }

      case _CRT_ERROR:
      {
         printf("_CRT_ERROR");
         break;
      }

      default:
      {
         printf("???Unknown???");
         break;
      }
   }

   printf("\".\nCRT report message is:\n\t");
   printf(szMsg);

   if   (pnRet)
      *pnRet = 0;

   return   nRet;
}

int __cdecl   TestHook2(int nReportType, char* szMsg, int* pnRet)
{
   int   nRet = FALSE;

   printf("CRT report hook 2.\n");
   printf("CRT report type is \"");
   switch   (nReportType)
   {
      case _CRT_WARN:
      {
         printf("_CRT_WARN");
         break;
      }

      case _CRT_ERROR:
      {
         printf("_CRT_ERROR");
         break;
      }

      case _CRT_ASSERT:
      {
         printf("_CRT_ASSERT");
         nRet = TRUE;   // Always stop for this type of report
         break;
      }

      default:
      {
         printf("???Unknown???");
         break;
      }
   }

   printf("\".\nCRT report message is: \t");
   printf(szMsg);

   if   (pnRet)
      *pnRet = 0;
   // printf("CRT report code is %d.\n", *pnRet);
   return   nRet;
}

int   main(int argc, char* argv[])
{
   int   nRet = 0;

   nRet = _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestHook1);
   printf("_CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestHook1)"
          " returned %d\n", nRet);
   nRet = _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestHook2);
   printf("_CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestHook2)"
          " returned %d\n", nRet);
   nRet = _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestHook2);
   printf("_CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestHook2)"
          " returned %d\n", nRet);
   nRet = _CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestHook1);
   printf("_CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestHook1)"
          " returned %d\n", nRet);
   nRet = _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestHook1);
   printf("_CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestHook1)"
          " returned %d\n", nRet);

   _ASSERT(0);

   nRet = _CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestHook2);
   printf("_CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestHook2)"
          " returned %d\n", nRet);
   nRet = _CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestHook2);
   printf("_CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestHook2)"
          " returned %d\n", nRet);
   nRet = _CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestHook2);
   printf("_CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestHook2)"
          " returned %d\n", nRet);
   nRet = _CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestHook1);
   printf("_CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestHook1)"
          " returned %d\n", nRet);

   return   nRet;
}

輸出

_CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestHook1) returned 0
_CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestHook2) returned 0
_CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestHook2) returned 0
_CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestHook1) returned 0
_CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestHook1) returned 0
_CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestHook2) returned 0
_CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestHook2) returned 0
_CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestHook2) returned 0
_CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestHook1) returned 0

另請參閱

偵錯常式