int n = 10;
CDebugConsole::GetInstance ().Printf ("n は %d です。", n);
// DebugConsole.h
#ifndef __DEBUGCONSOLE__H
#define __DEBUGCONSOLE__H
#include <windows.h>
#include <stdarg.h>
#ifdef __cplusplus
#ifdef DEBUGCONSOLE
#define __DBGINLINE
#else //DEBUGCONSOLE
#define __DBGINLINE {}
#endif //DEBUGCONSOLE
class CDebugConsole
{
public:
static CDebugConsole& GetInstance (void);
~CDebugConsole(void)__DBGINLINE;
void SetConsoleTitle (LPCTSTR lpszConsoleTitle)__DBGINLINE;
void Printf (LPCTSTR lpszFormat, ...)__DBGINLINE;
void Errorf (LPCTSTR lpszFormat, ...)__DBGINLINE;
void VPrintf (LPCTSTR lpszFormat, va_list args)__DBGINLINE;
void VErrorf (LPCTSTR lpszFormat, va_list args)__DBGINLINE;
void Dump (int nBytesBuffer, LPVOID lpBuffer, LPCTSTR lpszLabel = NULL)__DBGINLINE;
protected:
#ifdef DEBUGCONSOLE
BOOL m_bInitialized;
HANDLE m_hStdout;
HANDLE m_hStderr;
CRITICAL_SECTION m_csStdout;
CRITICAL_SECTION m_csStderr;
#endif //DEBUGCONSOLE
static CDebugConsole s_DebugConsole;
CDebugConsole(void)__DBGINLINE;
void WriteHandle (HANDLE hOutput, LPCTSTR lpszFormat, va_list args)__DBGINLINE;
};
#else //__cplusplus
#ifdef DEBUGCONSOLE
#define DbgSetConsoleTitle DebugSetConsoleTitle
#define DbgPrintf DebugPrintf
#define DbgErrorf DebugErrorf
#define DbgVPrintf DebugVPrintf
#define DbgVErrorf DebugVErrorf
#define DbgDump DebugDump
#else //DEBUGCONSOLE
#define DbgSetConsoleTitle 0? (void)0: DebugSetConsoleTitle
#define DbgPrintf 0? (void)0: DebugPrintf
#define DbgErrorf 0? (void)0: DebugErrorf
#define DbgVPrintf 0? (void)0: DebugVPrintf
#define DbgVErrorf 0? (void)0: DebugVErrorf
#define DbgDump 0? (void)0: DebugDump
#endif //DEBUGCONSOLE
void DebugSetConsoleTitle (LPCTSTR lpszConsoleTitle);
void DebugPrintf (LPCTSTR lpszFormat, ...);
void DebugErrorf (LPCTSTR lpszFormat, ...);
void DebugVPrintf (LPCTSTR lpszFormat, va_list args);
void DebugVErrorf (LPCTSTR lpszFormat, va_list args);
void DebugDump (int nBytesBuffer, LPVOID lpBuffer, LPCTSTR lpszLabel);
#endif //__cplusplus
#endif //__DEBUGCONSOLE__H
// DebugConsole.cpp
#include <stdio.h>
#include <signal.h>
#include "DebugConsole.h"
// 唯一のインスタンス
CDebugConsole CDebugConsole::s_DebugConsole;
CDebugConsole& CDebugConsole::GetInstance (void)
{
return s_DebugConsole;
}
#ifdef DEBUGCONSOLE
CDebugConsole::CDebugConsole(void)
: m_bInitialized(FALSE), m_hStderr (NULL), m_hStdout (NULL)
{
if (AllocConsole ())
{
signal (SIGINT, SIG_IGN);
m_hStdout = GetStdHandle (STD_OUTPUT_HANDLE);
if (INVALID_HANDLE_VALUE != m_hStdout)
{
m_hStderr = GetStdHandle (STD_ERROR_HANDLE);
if (INVALID_HANDLE_VALUE != m_hStderr)
{
InitializeCriticalSection (&m_csStdout);
InitializeCriticalSection (&m_csStderr);
m_bInitialized = TRUE;
return;
}
CloseHandle (m_hStdout);
}
FreeConsole ();
}
}
CDebugConsole::~CDebugConsole(void)
{
if (m_bInitialized)
{
FreeConsole ();
DeleteCriticalSection (&m_csStdout);
DeleteCriticalSection (&m_csStderr);
}
}
void CDebugConsole::SetConsoleTitle (LPCTSTR lpszConsoleTitle)
{
if (!m_bInitialized)
{
return;
}
::SetConsoleTitle (lpszConsoleTitle);
}
void CDebugConsole::Printf (LPCTSTR lpszFormat, ...)
{
if (!m_bInitialized)
{
return;
}
va_list args;
va_start (args, lpszFormat);
VPrintf (lpszFormat, args);
va_end (args);
}
void CDebugConsole::Errorf (LPCTSTR lpszFormat, ...)
{
if (!m_bInitialized)
{
return;
}
va_list args;
va_start (args, lpszFormat);
VErrorf (lpszFormat, args);
va_end (args);
}
void CDebugConsole::VPrintf (LPCTSTR lpszFormat, va_list args)
{
if (!m_bInitialized)
{
return;
}
EnterCriticalSection (&m_csStdout);
WriteHandle (m_hStdout, lpszFormat, args);
LeaveCriticalSection (&m_csStdout);
}
void CDebugConsole::VErrorf (LPCTSTR lpszFormat, va_list args)
{
if (!m_bInitialized)
{
return;
}
EnterCriticalSection (&m_csStderr);
WriteHandle (m_hStderr, lpszFormat, args);
LeaveCriticalSection (&m_csStderr);
}
void CDebugConsole::Dump (int nBytesBuffer, LPVOID lpBuffer, LPCTSTR lpszLabel)
{
if (!m_bInitialized)
{
return;
}
SYSTEMTIME LocalTime;
ZeroMemory (&LocalTime, sizeof (SYSTEMTIME));
GetLocalTime (&LocalTime);
LPTSTR lpszLabelTemp = _T ("");
if (lpszLabel)
{
lpszLabelTemp = const_cast <LPTSTR> (lpszLabel);
}
LPTSTR lpszHeader = NULL;
DWORD dwAlloc = 0;
DWORD dwHeaderSize = -1;
while (-1 == dwHeaderSize)
{
dwAlloc += 1024;
delete [] lpszHeader;
lpszHeader = new TCHAR [dwAlloc];
if (!lpszHeader)
{
return;
}
dwHeaderSize = _sntprintf (lpszHeader, dwAlloc, _T ("%04d/%02d/%02d %02d:%02d:%02d.%03d %dbytes [%s]\n"
" +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 1234567890ABCDEF\n")
, LocalTime.wYear
, LocalTime.wMonth
, LocalTime.wDay
, LocalTime.wHour
, LocalTime.wMinute
, LocalTime.wSecond
, LocalTime.wMilliseconds
, nBytesBuffer
, lpszLabelTemp);
}
if (WriteFile (m_hStdout, lpszHeader, dwHeaderSize, &dwHeaderSize, NULL))
{
LPBYTE lpbBuffer = (LPBYTE)lpBuffer;
int nWritten = 0;
DWORD dwWritten = 0;
while (nWritten < nBytesBuffer)
{
// 0----+----1----+----2----+----3----+----4----+----5----+----6
TCHAR szLine [] = _T (" ");
TCHAR szHex [] = _T (" ");
TCHAR szAscii [] = _T (" ");
LPTSTR lpszHexPtr = szHex;
LPTSTR lpszAsciiPtr = szAscii;
_stprintf (szLine, _T ("%08X"), nWritten);
do
{
_stprintf (lpszHexPtr, _T (" %02X"), *lpbBuffer);
lpszHexPtr += 3;
if (0x20 > *lpbBuffer)
{
*lpszAsciiPtr = _T ('.');
}
else
{
*lpszAsciiPtr = (TCHAR) *lpbBuffer;
}
lpszAsciiPtr ++;
lpbBuffer ++;
nWritten ++;
} while ((nWritten % 0x00000010) && (nWritten < nBytesBuffer));
while (nWritten % 0x00000010)
{
lstrcpy (lpszHexPtr, _T (" "));
lpszHexPtr += 3;
*lpszAsciiPtr ++ = _T (' ');
nWritten ++;
}
if (WriteFile (m_hStdout, szLine, 8, &dwWritten, NULL))
{
if (WriteFile (m_hStdout, szHex, 3 * 16 + 2, &dwWritten, NULL))
{
if (WriteFile (m_hStdout, szAscii, 16, &dwWritten, NULL))
{
if (WriteFile (m_hStdout, _T ("\r\n"), sizeof _T ("\r\n") - 1, &dwWritten, NULL))
{
continue;
}
}
}
}
nWritten = nBytesBuffer;
return;
}
WriteFile (m_hStdout, _T ("\r\n"), sizeof _T ("\r\n") - 1, &dwWritten, NULL);
}
delete [] lpszHeader;
}
void CDebugConsole::WriteHandle (HANDLE hOutput, LPCTSTR lpszFormat, va_list args)
{
if (!m_bInitialized)
{
return;
}
LPTSTR lpszMessage = NULL;
DWORD dwAlloc = 0;
DWORD dwMessageSize = -1;
while (-1 == dwMessageSize)
{
dwAlloc += 1024;
delete [] lpszMessage;
lpszMessage = new TCHAR [dwAlloc];
if (!lpszMessage)
{
return;
}
dwMessageSize = _vsntprintf (lpszMessage, dwAlloc, lpszFormat, args);
}
SYSTEMTIME LocalTime;
TCHAR szHeader [256];
ZeroMemory (&LocalTime, sizeof (SYSTEMTIME));
ZeroMemory (szHeader, sizeof szHeader);
GetLocalTime (&LocalTime);
DWORD dwHeaderSize = _stprintf (szHeader, _T ("%04d/%02d/%02d %02d:%02d:%02d.%03d ")
, LocalTime.wYear
, LocalTime.wMonth
, LocalTime.wDay
, LocalTime.wHour
, LocalTime.wMinute
, LocalTime.wSecond
, LocalTime.wMilliseconds);
if (WriteFile (hOutput, szHeader, dwHeaderSize, &dwHeaderSize, NULL))
{
if (WriteFile (hOutput, lpszMessage, dwMessageSize, &dwMessageSize, NULL))
{
WriteFile (hOutput, _T ("\r\n"), sizeof _T ("\r\n") - 1, &dwAlloc, NULL);
}
}
delete [] lpszMessage;
lpszMessage = NULL;
}
#endif //DEBUGCONSOLE
extern "C"
{
void DebugSetConsoleTitle (LPCTSTR lpszConsoleTitle)
{
CDebugConsole::GetInstance ().SetConsoleTitle (lpszConsoleTitle);
}
void DebugPrintf (LPCTSTR lpszFormat, ...)
{
va_list args;
va_start (args, lpszFormat);
CDebugConsole::GetInstance ().VPrintf (lpszFormat, args);
va_end (args);
}
void DebugErrorf (LPCTSTR lpszFormat, ...)
{
va_list args;
va_start (args, lpszFormat);
CDebugConsole::GetInstance ().VErrorf (lpszFormat, args);
va_end (args);
}
void DebugVPrintf (LPCTSTR lpszFormat, va_list args)
{
CDebugConsole::GetInstance ().VPrintf (lpszFormat, args);
}
void DebugVErrorf (LPCTSTR lpszFormat, va_list args)
{
CDebugConsole::GetInstance ().VErrorf (lpszFormat, args);
}
void DebugDump (int nBytesBuffer, LPVOID lpBuffer, LPCTSTR lpszLabel)
{
CDebugConsole::GetInstance ().Dump (nBytesBuffer, lpBuffer, lpszLabel);
}
}; //extern "C"