Windows AP にコンソール出力を提供するクラス
表題の通りです。コメントもありません。DEBUGCONSOLE
が定義されている場合のみコンソールが作成されます。
CDebugConsole クラスのメンバを以下に示します。
- GetInstance
- 唯一のインスタンスへの参照を返します
- SetConsoleTitle
- コンソールのタイトルバー文字列を更新します
- Printf
- 標準出力に書式付きで出力します
- Errorf
- 標準エラー出力に書式付きで出力します
- VPrintf
- 引数リストへのポインタを使用して、標準出力に書式付きで出力します
- VErrorf
- 引数リストへのポインタを使用して、標準エラー出力に書式付きで出力します
- Dump
- 渡されたデータを16進でダンプした結果を標準出力に出力します
CDebugConsole クラスのインスタンスは1個のみの存在とし、CDebugConsole::GetInstance ()
で参照を取得します。
int n = 10; CDebugConsole::GetInstance ().Printf ("n は %d です。", n);
また、C ソースにインクルードした場合に同等の機能を提供する関数も定義しています。
// 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"
トラックバック
- このエントリーにトラックバック:
- http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/1022
コメント