Win32 개발환경에서 VC++을 사용하면 디버그 모드에서 TRACE라는 매크로를 사용하여 디버그 결과창에 디버깅중 점검해야 할 내용들을 쉽게 볼 수 있도록 화면에 찍어줄 수 있는데, MFC를 사용하지 않거나 릴리즈 모드에서도 이걸 사용하고 싶을때 활용하는 방법..
우선 www.sysinternals.com 사이트에 가서 DebugView 라는 프로그램을 다운로드 받는다.. 이 프로그램은 디버그 결과창에 나오는 내용을 볼 수 있도록 해주는 어플리케이션인데, 디버그로 빌드가 되었건 릴리즈로 빌드가 되었건 상관없이 디버그 결과창에 찍히는 문자열들을 보여준다.. 릴리즈로 실행시에는 VS의 디버거로 실행되지 않으니 디버그 결과창을 볼 수 없으니 이 프로그램이 필요하다.. 물론, 디버그 모드로 빌드된 어플리케이션도 느리고 덩치큰 디버거와 함껫 실행시키는 것 보다 이 어플리케이션으로 확인해보는게 편한 경우도 많으므로 꽤 유용한 프로그램이다.. 이런 어플리케이션은 열심히 사용을 해줘야 한다..
TRACE 매크로는 디버그로 빌드된 경우만 동작하도록 작성되어 있으므로 TRACE 매크로 소스를 수정해서 사용하는 방법이 하나가 있겠고, TRACE 매크로 소스를 보고 릴리즈에서도 동작하도록 내가 만들서 쓰는 방법이 있다..
이와 같은 욕구는 이미 다른 개발자들도 가지고 있었을 것이고, 인터넷을 뒤져보면 아래와 같은 함수를 찾을 수 있는데, 릴리즈 모드 및 MFC를 사용하지 않는 Win32 API만 사용해야 하는 경우에 사용할 수 있다.. (나 같은 경우는 심심풀이로 Win32 게임을 만들면서 사용을 하려고 찾았었는데, 아직도 게임을 MFC로 만들면 안된다는데는 공감을 못하고 있다.. 흐흐흐.. 그때 찾은 출처를 남겨놨어야 하는데, 암튼 어디서 찾았는지 지금은 모르겠고, 다시 찾기는 좀 귀찮고.. 암튼 확실한건 내가 작성한 소스는 아니다..)
#include "stdio.h"
void Trace(char* szFormat, ...)
{
char szTempBuf[2048] ;
va_list vlMarker ;
va_start(vlMarker,szFormat) ;
vsprintf(szTempBuf,szFormat,vlMarker) ;
va_end(vlMarker) ;
OutputDebugString(szTempBuf) ;
}
이제 준비가 다 되었으니 TRACE를 쓰고 싶은 경우에 위의 함수를 사용하고, 위에서 설명한 어플리케이션을 띄워두면 된다.. 물론, 불필요한 코드가 호출되고 링크되는 것이 영 눈에 거슬린다면 매크로를 사용해서 디버그인 경우만 포함되도록 컨디셔널 컴파일 구성을 하면 되겠다..
보는 바와 같이 C 언어를 알면 해결할 수 있는 함수들로 구성되어 있고 모르는 API는 OutputDebugString 하나 뿐이다.. 의외로 이 API가 디버그 모드에서만 동작하는 것으로 아는 사람들이 많은데, 이름만 보고 섵부른 판단은 금물이다.. 궁금하면 직접 해보면 되는데, 사실 이런 궁금증을 가지는 사람도, 직접 궁금증을 해결하기 위해 행동하는 사람도 비교적 적은 것 같아 아쉽다..
프로그래밍 뿐만 아니라 무슨 일을 하던, 이건 이럴거야 라고 선입견을 가지기 전에 정말로 그런지 약간의 시간을 들여 확인을 해보면 많은 도움이 될 것 같다는 생각이 든다.. 아마, 이 함수는 많은 개발자들이 알고 있거나 이미 사용하고 있겠지만, 역시나 또 많은 개발자들이 이렇게 활용하는 방법이 있을 거라는 것 조차 모르고 넘어가고 있는 것 같아 (릴리즈에서는 디버그 문자열을 확인할 방법이 없네.. 걍 디버그로 하자.. 이런 자세.. 음, 좋지 않다..) 기록을 남겨본다..
물론, 나 역시 여러 상황에서 위와 같은 태도를 보이는 경우가 많긴 하지만 스스로 그러한 것들을 깨려고 노력할때 명랑 코딩 사회 건설에 도움이 되지 않을까 싶다.. 우선 명랑 코딩 사회 건설을 위해 프로그래밍은 3D라는 이야기 부터 우리 입에서 없애도록 하자.. 그러기 위해 오늘도 열심히 실력 연마를 위해 힘 내자구~
===================================================
실제 적용 - 1
===================================================
Visual C++에서 API 등 MFC가 아닌 프로그램을 작성할 때 TRACE 매크로 처럼
Output 창에 값을 출력하려면 다음과 같은 매크로를 작성하여 사용하면 된다.
파일에 기록하는 것도 유사하게 작성하면 되겠다.
**
#include <windows.h>
#include <stdio.h>
#ifdef _DEBUG
#define TRACEf Tracef
#else
#define TRACEf ((void)0)
#endif
#ifdef _DEBUG
#define MAX_MSG_SIZE 1024 // 1K 넘는건 보내지마! -_-x
void TRACEf(const char *szString, ...)
{
static char szBuffer[MAX_MSG_SIZE];
va_list argptr = NULL;
va_start(argptr, szString);
vsprintf(szBuffer, szString, argptr);
OutputDebugString(szBuffer);
va_end(argptr);
}
#endif
**
사용은 TRACE 매크로처럼 원하는 곳에서
**
TRACEf("s = %lf | t = %lf | u = %lf\n", s, t, u);
**
이렇게 하면된다. 당연히 릴리즈 모드일 때는 제외된다.
...
===================================================
실제 적용 - 2 : 파일로 작성
===================================================
void Global_WriteLog(const char* msg ...)
{
SYSTEMTIME st;
GetLocalTime(&st);
char szCurTime[100] = {0, };
_stprintf(szCurTime, "[%04d/%02d/%02d %02d:%02d:%02d.%04d] ",
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
TCHAR szLogPath[MAX_PATH] = {0, };
wsprintf(szLogPath, "%s\\PTCAgent.log", g_szClientLogPath);
g_fpLog = fopen(szLogPath, "a+");
fprintf(g_fpLog, szCurTime);
va_list ap;
va_start(ap, msg);
vfprintf(g_fpLog, msg, ap);
fclose(g_fpLog);
}