_CrtSetReportHook2
, _CrtSetReportHookW2
Instaluje lub odinstalowuje funkcję raportowania zdefiniowaną przez klienta, podłączając ją do procesu raportowania debugowania w czasie wykonywania języka C (tylko wersja debugowania).
Składnia
int _CrtSetReportHook2(
int mode,
_CRT_REPORT_HOOK pfnNewHook
);
int _CrtSetReportHookW2(
int mode,
_CRT_REPORT_HOOKW pfnNewHook
);
Parametry
mode
Akcja do wykonania: _CRT_RPTHOOK_INSTALL
lub _CRT_RPTHOOK_REMOVE
.
pfnNewHook
Punkt zaczepienia raportu, aby zainstalować lub usunąć w wersji wąsko-znakowej lub szerokiej wersji tej funkcji.
Wartość zwracana
-1, jeśli wystąpił błąd z EINVAL
lub ENOMEM
ustawiony; w przeciwnym razie zwraca liczbę pfnNewHook
odwołań po wywołaniu.
Uwagi
_CrtSetReportHook2
i _CrtSetReportHookW2
pozwala podłączyć lub odpiąć funkcję, podczas gdy _CrtSetReportHook
tylko pozwala podłączyć funkcję.
_CrtSetReportHook2
lub _CrtSetReportHookW2
należy użyć zamiast _CrtSetReportHook
, gdy wywołanie haka jest wykonywane w dll i kiedy można załadować wiele bibliotek DLL i ustawić własne funkcje zaczepienia. W takiej sytuacji biblioteki DLL można zwolnić w innej kolejności niż zostały załadowane, a funkcja haka może wskazywać na zwolniony plik DLL. Wszystkie dane wyjściowe debugowania powoduje awarię procesu, jeśli funkcje zaczepienia zostały dodane za pomocą polecenia _CrtSetReportHook
.
Wszystkie dodane _CrtSetReportHook
funkcje punktów zaczepienia są wywoływane, jeśli nie dodano żadnych funkcji punktów zaczepienia z _CrtSetReportHook2
lub _CrtSetReportHookW2
czy wszystkie funkcje zaczepienia dodane za pomocą _CrtSetReportHook2
polecenia i _CrtSetReportHookW2
zwracają FALSE
wartość .
Dostępna jest szeroka wersja tej funkcji. Funkcje zaczepienia raportu przyjmują ciąg, którego typ (szerokie lub wąskie znaki) musi być zgodny z wersją używanej funkcji. Użyj następującego prototypu funkcji dla punktów zaczepienia raportu używanych z szeroką wersją tej funkcji:
int YourReportHook( int reportType, wchar_t *message, int *returnValue );
Użyj następującego prototypu dla zawężnych punktów zaczepienia raportu:
int YourReportHook( int reportType, char *message, int *returnValue );
Te funkcje weryfikują swoje parametry. Jeśli mode
lub pfnNewHook
jest nieprawidłowy, te funkcje wywołują nieprawidłową procedurę obsługi parametrów zgodnie z opisem w temacie Weryfikacja parametrów. Jeśli wykonanie może kontynuować, te funkcje są ustawione errno
na EINVAL
wartość i zwracają wartość -1.
Uwaga
Jeśli aplikacja jest kompilowana z /clr i funkcja raportowania jest wywoływana po zakończeniu działania aplikacji głównej, clR zgłosi wyjątek, jeśli funkcja raportowania wywołuje jakiekolwiek funkcje CRT.
Wymagania
Procedura | Wymagany nagłówek | Opcjonalny nagłówek |
---|---|---|
_CrtSetReportHook2 |
<crtdbg.h> | <errno.h> |
_CrtSetReportHookW2 |
<crtdbg.h> | <errno.h> |
Aby uzyskać więcej informacji o zgodności, zobacz Zgodność.
Biblioteki
Debugowanie tylko wersji bibliotek czasu wykonywania języka C.
Przykład
// 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;
}
Wynik
_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