vc6下支持格式化输出的调试输出功能的简单实现
VC下没有支持可变参数的调试输出实现.今天捣鼓了半天做了一个简单的:)
// dgb_prt.h
#include
<
windows.h
>
#define _DEBUG_INFO_FILE "gfx_dbg_info.txt" // 修改这里的输出文件
VOID _cdecl __DPrt( const WCHAR * fmt, );
VOID _cdecl __RPrt( const WCHAR * fmt, );
VOID _cdecl __ADPrt(BOOL, const WCHAR * fmt, );
VOID _cdecl __ARPrt(BOOL, const WCHAR * fmt, );
#ifndef NDEBUG
# define _DbgPrt __DPrt
#else
# define _DbgPrt __RPrt
#endif
#ifndef NDEBUG
# define _AstPrt __ADPrt
#else
# define _AstPrt __ARPrt
#endif
#define _DEBUG_INFO_FILE "gfx_dbg_info.txt" // 修改这里的输出文件
VOID _cdecl __DPrt( const WCHAR * fmt, );
VOID _cdecl __RPrt( const WCHAR * fmt, );
VOID _cdecl __ADPrt(BOOL, const WCHAR * fmt, );
VOID _cdecl __ARPrt(BOOL, const WCHAR * fmt, );
#ifndef NDEBUG
# define _DbgPrt __DPrt
#else
# define _DbgPrt __RPrt
#endif
#ifndef NDEBUG
# define _AstPrt __ADPrt
#else
# define _AstPrt __ARPrt
#endif
// dbg_prt.cpp
//
-------------------------------------------------------------------------
#define _STDOUT_FP (1)
#define _DEBUG_INFO_FILE "dbg_info.txt"
// -------------------------------------------------------------------------
typedef struct __DbgPrtPara
{
FILE *pfp;
int pfd;
unsigned long pret;
} _DbgPrtPara, * _PDbgPrtPara;
_PDbgPrtPara __stdcall __DPrtInit()
{
_PDbgPrtPara pDbgPara = (_PDbgPrtPara)malloc(sizeof(_DbgPrtPara));
pDbgPara->pfd = _dup(_STDOUT_FP);
pDbgPara->pfp = freopen(_DEBUG_INFO_FILE, "a+", stdout);
unsigned short buff[128] = {'\0'};
_wstrtime(buff);
wprintf(L"%s: ", buff);
return pDbgPara;
}
void __stdcall __DPrtClose(_PDbgPrtPara pDbgPara)
{
fflush(pDbgPara->pfp);
fclose(pDbgPara->pfp);
_dup2(pDbgPara->pfd, _STDOUT_FP);
free(pDbgPara);
pDbgPara = NULL;
}
// -------------------------------------------------------------------------
__declspec(naked) void __DPrt( const unsigned short * fmt, )
{
#ifdef _M_IX86
__asm{
call __DPrtInit
pop ebx
mov dword ptr [eax + 8], ebx
mov ebx, eax
call dword ptr [wprintf]
push ebx
mov eax, dword ptr [ebx + 8]
mov ebx, eax
call __DPrtClose
push ebx
ret
}
#endif
}
// -------------------------------------------------------------------------
void __RPrt( const unsigned short * fmt, )
{
}
// -------------------------------------------------------------------------
__declspec(naked) void __ADPrt(unsigned long , const unsigned short * fmt, )
{
#ifdef _M_IX86
__asm{
mov eax, dword ptr [esp + 4]
cmp eax, 0
je EXE_TRUE
ret
EXE_TRUE:
call __DPrtInit
pop ebx
mov dword ptr [eax + 8], ebx
mov ebx, eax
pop eax
call dword ptr [wprintf]
push ebx
mov eax, dword ptr [ebx + 8]
mov ebx, eax
call __DPrtClose
sub esp, 4
push ebx
ret
}
#endif
}
// -------------------------------------------------------------------------
void _cdecl __ARPrt(unsigned long , const unsigned short * fmt, )
{
}
// -------------------------------------------------------------------------
#define _STDOUT_FP (1)
#define _DEBUG_INFO_FILE "dbg_info.txt"
// -------------------------------------------------------------------------
typedef struct __DbgPrtPara
{
FILE *pfp;
int pfd;
unsigned long pret;
} _DbgPrtPara, * _PDbgPrtPara;
_PDbgPrtPara __stdcall __DPrtInit()
{
_PDbgPrtPara pDbgPara = (_PDbgPrtPara)malloc(sizeof(_DbgPrtPara));
pDbgPara->pfd = _dup(_STDOUT_FP);
pDbgPara->pfp = freopen(_DEBUG_INFO_FILE, "a+", stdout);
unsigned short buff[128] = {'\0'};
_wstrtime(buff);
wprintf(L"%s: ", buff);
return pDbgPara;
}
void __stdcall __DPrtClose(_PDbgPrtPara pDbgPara)
{
fflush(pDbgPara->pfp);
fclose(pDbgPara->pfp);
_dup2(pDbgPara->pfd, _STDOUT_FP);
free(pDbgPara);
pDbgPara = NULL;
}
// -------------------------------------------------------------------------
__declspec(naked) void __DPrt( const unsigned short * fmt, )
{
#ifdef _M_IX86
__asm{
call __DPrtInit
pop ebx
mov dword ptr [eax + 8], ebx
mov ebx, eax
call dword ptr [wprintf]
push ebx
mov eax, dword ptr [ebx + 8]
mov ebx, eax
call __DPrtClose
push ebx
ret
}
#endif
}
// -------------------------------------------------------------------------
void __RPrt( const unsigned short * fmt, )
{
}
// -------------------------------------------------------------------------
__declspec(naked) void __ADPrt(unsigned long , const unsigned short * fmt, )
{
#ifdef _M_IX86
__asm{
mov eax, dword ptr [esp + 4]
cmp eax, 0
je EXE_TRUE
ret
EXE_TRUE:
call __DPrtInit
pop ebx
mov dword ptr [eax + 8], ebx
mov ebx, eax
pop eax
call dword ptr [wprintf]
push ebx
mov eax, dword ptr [ebx + 8]
mov ebx, eax
call __DPrtClose
sub esp, 4
push ebx
ret
}
#endif
}
// -------------------------------------------------------------------------
void _cdecl __ARPrt(unsigned long , const unsigned short * fmt, )
{
}
// -------------------------------------------------------------------------
当然,如果要实时看到输出,可以用 FindFirstChangeNotification、FindNextChangeNotification、FILE_NOTIFY_CHANGE_LAST_WRITE等来实现一个动态监视并输出的程序.
这样就有点象ddk里的DbgPrint了,呵呵.