_CrtSetReportHook2、_CrtSetReportHookW2
更新 : 2007 年 11 月
クライアント定義のレポート関数を 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
この関数のナロー文字のバージョンでインストールまたは削除するレポート フック。pfnNewHook
この関数のワイド文字のバージョンでインストールまたは削除するレポート フック。
戻り値
エラーが検出された場合は -1 を返し、EINVAL または ENOMEM をセットします。それ以外の場合は、呼び出し後の pfnNewHook の参照カウントを返します。
解説
_CrtSetReportHook2 と _CrtSetReportHookW2 では関数をフックまたはアンフックできますが、_CrtSetReportHook ではフックしかできません。
DLL でフック呼び出しを行うとき、および複数の DLL を読み込んで独自のフック関数を設定するときは、_CrtSetReportHook の代わりに _CrtSetReportHook2 または _CrtSetReportHookW2 を使用する必要があります。そのような状況では、DLL は読み込まれた順序とは異なる順序でアンロードでき、フック関数がアンロードされた DLL を指したままの状態にすることができます。_CrtSetReportHook を使用してフック関数を追加した場合、デバッグ出力によってプロセスがクラッシュされます。
_CrtSetReportHook2 または _CrtSetReportHookW2 を使用して追加したフック関数が他にない場合、または _CrtSetReportHook2 と _CrtSetReportHookW2 を使用して追加したすべてのフック関数が FALSE を返す場合は、_CrtSetReportHook を使用して追加したフック関数が呼び出されます。
この関数のワイド文字のバージョンは、Visual C++ 2005 で使用できます。レポート フック関数は、型 (ワイド文字またはナロー文字) が関数のバージョンに一致する文字列を受け取ります。この関数のワイド文字のバージョンで使用するレポート フックには、次の関数プロトタイプを使用します。
int YourReportHook( int reportType, wchar_t *message, int *returnValue );
ナロー文字のレポート フックには、次のプロトタイプを使用します。
int YourReportHook( int reportType, char *message, int *returnValue );
これらの関数では、パラメータの検証が行われます。mode または pfnNewNook が無効の場合、「パラメータの検証」に説明されているように、この関数は無効なパラメータ ハンドラを呼び出します。実行の継続が許可された場合、これらの関数は errno を EINVAL に設定し、-1 を返します。
メモ : |
---|
アプリケーションが /clr でコンパイルされ、アプリケーションがメイン関数を出た後でレポート関数が呼び出された場合、レポート関数が CRT 関数を呼び出すと、CLR が例外をスローします。 |
必要条件
ルーチン |
必須ヘッダー |
オプション ヘッダー |
---|---|---|
_CrtSetReportHook2 |
<crtdbg.h> |
<errno.h> |
_CrtSetReportHookW2 |
<crtdbg.h> |
<errno.h> |
互換性の詳細については、「C ランタイム ライブラリ」の「互換性」を参照してください。
ライブラリ
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