_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,並會設定 EINVAL
或 ENOMEM
;否則會在呼叫後傳回 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 );
這些函式會驗證它們的參數。 如果 mode
或 pfnNewHook
無效,這些函式會叫用無效的參數處理程式,如參數驗證中所述。 如果允許繼續執行,這些函式會將 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