%>
通过以下方式安装或卸载客户端定义的报告函数:将该函数挂钩到 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
要在此函数的窄字符版本或宽字符版本中安装或移除的报告挂钩。
返回值
如果出现错误,并设置了 EINVAL
或 ENOMEM
,则为 -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 );
这些函数验证其参数。 如果 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