_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 только позволяет перехватить функцию.

_CrtSetReportHook2 или _CrtSetReportHookW2следует использовать вместо _CrtSetReportHook, когда вызов обработчика производится в DLL и могут быть загружены несколько DLL, в каждой из которых могут настраиваться собственные функции-обработчики. В таком случае библиотеки DLL могут быть выгружены не в том порядке, в котором они были загружены, а функция-обработчик может продолжать указывать на выгруженную библиотеку DLL. Любой отладочный вывод вызывает сбой процесса, если функции-обработчики были добавлены с помощью _CrtSetReportHook.

Все функции-обработчики, добавленные с помощью функции _CrtSetReportHook, вызываются при отсутствии функций-обработчиков, добавленных с помощью функции _CrtSetReportHook2 или _CrtSetReportHookW2, либо если все функции-обработчики, добавленные с помощью функций _CrtSetReportHook2 и _CrtSetReportHookW2, возвращают значение FALSE.

Доступна версия этой функции для расширенных символов. Функции-обработчики отчетов принимают строку, тип которой (расширенные или обычные символы) должен соответствовать версии используемой функции. Используйте следующий прототип функции для обработчиков отчетов, используемых с версией этой функции для расширенных символов:

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

Используйте следующий прототип для обработчиков отчетов с обычными символами:

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

Эти функции проверяют свои параметры. Если mode это pfnNewHook недопустимо, эти функции вызывают обработчик недопустимых параметров, как описано в разделе "Проверка параметров". Если продолжение выполнения разрешено, эти функции устанавливают для errno значение EINVAL и возвращают -1.

Примечание.

Если приложение компилируется с помощью /clr и функция создания отчетов вызывается после выхода приложения из основного кода, среда CLR выдает исключение, если функция отчетов вызывает какие-либо функции CRT.

Требования

Маршрут Обязательный заголовок Необязательный заголовок
_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

См. также

Отладка подпрограмм