코드 디버깅 경험 중 하나

7208 단어 windowsdebugVC
배경: 오래전 코드.일부 특정 환경에서 보조 디버깅에 사용됩니다.
코드를 디버깅하고 싶지만,release 버전에서 실제 코드를 생산하고 싶지 않아서, 나는 다음과 같은 헤더 파일을 썼다.
디버깅할 때 좀 편해요, 허허.
// DBG_HELPER.H
//  [4/14/2010]
// BY qinchong637#gmail.com
//////////////////////////////////////////////////////////////////////////
//   :
//       <<        、  、   。
//     :
//               _DEBUG       , release        
//            、   release          ,         
// 
// _DBG_PROMPT :              
// dbg2console :          
// dbg2debugger :          ,    Windows   。
// dbg2file :         
// dbg2file_global : dbg2file       (        ,                    ),           
//   :
//     1、 release     dbg2file_global     ,     ()             ,
//               ,        ,                ,           
//     2、         ,   static_cast,          ,    。 :dbg2file()<<*pInt; => dbg2file()<<static_cast<int>(*pInt);
//////////////////////////////////////////////////////////////////////////

#pragma once
#ifndef _DBG_HELPER_H_QC637_FSEYE_HOTMAIL_528
#define _DBG_HELPER_H_QC637_FSEYE_HOTMAIL_528

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <tchar.h>

#ifdef WIN32
#include <windows.h>
#endif

#ifdef DBG_DEFAULT_MT_POLICY
	#pragma message("*** DBG_HELPER.H : Another DBG_DEFAULT_MT_POLICY defined anywhere alse and this maybe cause an error***")	
#else
	#ifdef _DBG_SINGLE_THREADED
	#define DBG_DEFAULT_MT_POLICY single_threaded
	#else
	#define DBG_DEFAULT_MT_POLICY multi_threaded
#endif

#endif

#define _DBG_FILE_VERSION _T("1.0.0")

#ifdef _DBG_PROMPT
	#pragma message("*** DBG_HELPER.H : Another _DBG_PROMPT defined anywhere else and this maybe cause a an error***")
#else
	#define _DBG_PROMPT __FILE__##<<_T(": ")<<__LINE__<<_T(": ")
#endif


//   UNICODE    
#if defined _UNICODE
typedef std::wstring		tstring;
typedef std::wostringstream	tostringstream;
typedef std::wostream		tostream;
typedef std::wofstream		tofstream;
typedef std::wstringstream	tstringstream;

#define tcout				std::wcout
#else
typedef std::string			tstring;
typedef std::ostringstream	tostringstream;
typedef std::stringstream	tstringstream;
typedef std::ostream		tostream;
typedef std::ofstream		tofstream;

#define	tcout				std::cout
#endif

namespace dbg{

class single_threaded
{
public:
	single_threaded(){}
	virtual ~single_threaded(){}

	virtual void lock(){}
	virtual void unlock(){}
private:
};

#ifdef WIN32
class multi_threaded
{
public:
	multi_threaded(){
#ifdef _DEBUG
		static bool isinitialised = false;
		if (!isinitialised) {
			InitializeCriticalSection(get_critsec());
			isinitialised = true;
		}
#endif
	}

	multi_threaded(const multi_threaded &) {;}

	virtual ~multi_threaded(){}
	virtual void lock() {
#ifdef _DEBUG
		EnterCriticalSection(get_critsec());
#endif
	}

	virtual void unlock() {
#ifdef _DEBUG
		LeaveCriticalSection(get_critsec());
#endif
	}

private:
#ifdef _DEBUG
	CRITICAL_SECTION *get_critsec()
	{
		static CRITICAL_SECTION g_critsec;
		return &g_critsec;
	}
#endif
};
#endif	// end of WIN32

template<class mt_policy=DBG_DEFAULT_MT_POLICY>
class glock_dbg : public mt_policy
{

};

template<class mt_policy=DBG_DEFAULT_MT_POLICY>
class lock_block : public mt_policy
{
public:

	lock_block() {this->lock();}
	~lock_block() {this->unlock();}
};

// 
class dbg2console 
{
};

class dbg2debugger
{
};

#ifdef _DEBUG
	
class dbg2file_global;
class dbg2file 
{
public:
	dbg2file(const TCHAR *szFile, std::ios::openmode mode=std::ios::out) 
	{
		// vc6  UNICODE     ,  vc6 fstream open   wchar_t
		ostr_.open(szFile, mode);
	}
	~dbg2file() 
	{
		if (ostr_.is_open()) {
			ostr_.close();
		}
	}

public:
	tofstream ostr_;
private:
	dbg2file() {}
	void open(const TCHAR *szFile, std::ios::openmode mode=std::ios::out)
	{
		ostr_.open(szFile, mode);
	}

	friend class dbg2file_global;
};

class dbg2file_global
{
public:
	dbg2file_global(const TCHAR *szFile, std::ios::openmode mode=std::ios::out) 
	{
		static bool isinitialised = false;
		if (!isinitialised) {
			getInst().open(szFile, mode);
			isinitialised = true;
		}
	}
	~dbg2file_global() 
	{
	}

	dbg2file &operator()(){return getInst();}
private:
	static dbg2file& getInst()
	{
		static dbg2file ostr_;
		return ostr_;
	}
};

template<typename T>
inline dbg2file & operator <<(dbg2file &out, const T &obj)
{
	out.ostr_<<obj;
	return out;
}

template<typename T>
inline dbg2console & operator <<(dbg2console &out, const T &obj)
{
	tcout<<obj;
	return out;
}

template<typename T>
inline dbg2debugger & operator <<(dbg2debugger &out, const T &obj)
{
	tstringstream strs;
	strs<<obj;
	tstring str = strs.str();
	OutputDebugString(str.c_str());
	return out;
}


#else
// RELEASE VERSION
// Take the same interface as in the DEBUG version

class dbg2file 
{
public:
	dbg2file(const TCHAR *szFile, std::ios::openmode mode=std::ios::out|std::ios::app) 
	{
	}
	~dbg2file() 
	{
	}
};

class dbg2file_global
{
public:
	dbg2file_global(const TCHAR *szFile, std::ios::openmode mode=std::ios::out) 
	{
	}
	~dbg2file_global() 
	{
	}

	// have a warning here. but no problems.
	dbg2file &operator()(){return dbg2file(NULL, 0);}
private:
};

template<typename T>
inline dbg2file & operator <<(dbg2file &out, const T &obj)
{
	return out;
}

template<typename T>
inline dbg2console & operator <<(dbg2console &out, const T &obj)
{
	return out;
}

template<typename T>
inline dbg2debugger & operator <<(dbg2debugger &out, const T &obj)
{
	return out;
}

#endif // end of release version

}

#endif	// end of file

좋은 웹페이지 즐겨찾기