_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
要在此函数的窄字符版本或宽字符版本中安装或移除的报告挂钩。

返回值

如果出现错误,并设置了 EINVALENOMEM,则为 -1;否则,将在调用后返回 pfnNewHook 的引用计数。

备注

_CrtSetReportHook2_CrtSetReportHookW2 可用于挂钩或解除挂钩函数,而 _CrtSetReportHook 只能用于挂钩函数。

在 DLL 中进行挂钩调用时以及在可以加载多个 DLL 并设置其自己的挂钩函数时,应使用 _CrtSetReportHook2_CrtSetReportHookW2 而非 _CrtSetReportHook。 在此类情况下,可按与 DLL 的加载顺序不同的顺序来卸载 DLL,并且挂钩函数可以仍指向已卸载的 DLL。 如果已将挂钩函数与 _CrtSetReportHook 一起添加,则任何调试输出均会导致进程崩溃。

如果未将任何挂钩函数与 _CrtSetReportHook2_CrtSetReportHookW2 一起添加,则调用与 _CrtSetReportHook 一起添加的任何挂钩函数;或如果已将所有挂钩函数与 _CrtSetReportHook2_CrtSetReportHookW2一起添加,则返回 FALSE

此函数的宽字符版本可用。 报告挂钩函数采用一个其类型(宽字符或窄字符)必须与使用的此函数版本匹配的字符串。 将以下函数原型用于与此函数的宽字符版本一起使用的报告挂钩:

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

另请参阅

调试例程