wenjiang 的个人资料morning's blog照片日志列表更多 ![]() | 帮助 |
|
|
6月30日 实现了VC6 的 __FUNCTION__,附上一个调试辅助类利用 dbg api 实现了 vc6 下的 __FUNCTION__ ,意外发现 在使用 /ZI 时 VC7.1 的 __LINE__ 的实现很有意思.
源代码:
#ifdef __cplusplus
class clsT1 { public: virtual void Test(int x=0) { DbgPrint(_T("测试\n")); } }; class clsT2:public clsT1
{ public: void Test(int x=0) { DbgPrint(_T("测试\n")); clsT1::Test(x); } }; #endif
int main(int argc, char* argv[])
{ _TRACE_FUNCTION_(); DbgPrintA("测试\n"); DbgPrintW(L"测试\n"); #ifdef __cplusplus clsT2 _t2; _t2.Test(); #endif // getchar(); return 0; } 输出效果:
D:\My Documents\Visual C++ Projects\6.0\testcpp\testc.cpp(30) : <main>: ++
D:\My Documents\Visual C++ Projects\6.0\testcpp\testc.cpp(31) : <main>: 测试 D:\My Documents\Visual C++ Projects\6.0\testcpp\testc.cpp(32) : <main>: 测试 D:\My Documents\Visual C++ Projects\6.0\testcpp\testc.cpp(21) : <clsT2::Test>:测试 D:\My Documents\Visual C++ Projects\6.0\testcpp\testc.cpp(12) : <clsT1::Test>:测试 D:\My Documents\Visual C++ Projects\6.0\testcpp\testc.cpp(30) : <main>: --,Escaped:0 头文件(兼容C源代码,多线程安全的,因为内部的部分实现使用了线程存储,如果有人知道如何追踪C代码的函数过程的,请分享):
//------------------------------------------------------------------------------------------------------------------------------------------
// 参数 // _DBG_LIB_NAME ,用于控制输出的前缀 // 开关,关掉输出
#ifndef _DBG_GLOBAL_SWITCH #define _DBG_GLOBAL_SWITCH 1 #endif // 开关,是否总是使用 outputdebugstring,即使是在命令行模式下 #ifndef _DBG_FORCEDBGSTR_SWITCH #define _DBG_FORCEDBGSTR_SWITCH 0 #endif // 开关,是否仅显示 函数名(隐去 文件名,行号) #ifndef _DBG_SIMPLE_SWITCH #define _DBG_SIMPLE_SWITCH 0 #endif // 优化 assert 的行为
// assert 使用 MessageBox 提示,但是这会导致一些程序无法中断下来 // _ASSERT 会循环 MessageBox,不断弹出对话框 #ifndef _DBG_BREAKIN_ASSERT #define _DBG_BREAKIN_ASSERT 1 #endif //------------------------------------------------------------------------------------------------------------------------------------------
#ifdef __cplusplus extern "C"{ #endif // 取 EIP LIBBASE_API DWORD WINAPI GetEIP(); // __FUNCIOTN__ 模拟 #ifdef __SIMU_FUNCTION__ LIBBASE_API LPCSTR WINAPI GetFUNCTIONA(DWORD64 Address); LIBBASE_API LPCWSTR WINAPI GetFUNCTIONW(DWORD64 Address); #undef __FUNCTION__ #undef __WFUNCTION__ #define __FUNCTION__ GetFUNCTIONA(GetEIP()) #define __WFUNCTION__ GetFUNCTIONW(GetEIP()) #endif // __LINE__ 修正 #if _MSC_VER==1310 // 在 VC7.1 中,当设为 /ZI 时,__LINE__ 是 __LINE__Var + 1,所以,下面两个宏将无法正确展开 #define __SIMU_LINENO__ #undef __LINENO__ #undef __WLINENO__ LIBBASE_API LPCSTR WINAPI GetLINENOA(DWORD dwLine); LIBBASE_API LPCWSTR WINAPI GetLINENOW(DWORD dwLine); #define __LINENO__ GetLINENOA(__LINE__) #define __WLINENO__ GetLINENOW(__LINE__) #endif // 通用字符串连接 LIBBASE_API LPCSTR WINAPI LOC_STR_LINKA(LPCSTR psz,...); LIBBASE_API LPCWSTR WINAPI LOC_STR_LINKW(LPCWSTR psz,...); #ifdef __cplusplus }; #endif //------------------------------------------------------------------------------------------------------------------------------------------
// 预格式化 #if _DBG_SIMPLE_SWITCH #ifndef __SIMU_FUNCTION__ #define DEF_LOC_STDOUT_A "<" __FUNCTION__ ">: " #define DEF_LOC_STDOUT_W L"<" __WFUNCTION__ L">: " #else #define DEF_LOC_STDOUT_A LOC_STR_LINKA("<",__FUNCTION__,">: ",NULL) #define DEF_LOC_STDOUT_W LOC_STR_LINKW(L"<",__WFUNCTION__,L">: ",NULL) #endif #else #ifndef _DBG_LIB_NAME #define __DBG_LIB_NAMEA "" #define __DBG_LIB_NAMEW L"" #else #define __DBG_LIB_NAMEA "(" _DBG_LIB_NAME ")" #define __DBG_LIB_NAMEW L"(" _L(_DBG_LIB_NAME) L")" #endif #if !defined(__SIMU_FUNCTION__) && !defined(__SIMU_LINENO__) #define DEF_LOC_STDOUT_A __FILE__ "("__LINENO__") : " __DBG_LIB_NAMEA "<" __FUNCTION__ ">: " #define DEF_LOC_STDOUT_W __WFILE__ L"(" __WLINENO__ L") : " __DBG_LIB_NAMEW L"<" __WFUNCTION__ L">: " #else #define DEF_LOC_STDOUT_A LOC_STR_LINKA(__FILE__,"(",__LINENO__,") : ",__DBG_LIB_NAMEA,"<",__FUNCTION__,">: ",NULL) #define DEF_LOC_STDOUT_W LOC_STR_LINKW(__WFILE__,L"(",__WLINENO__,L") : ",__DBG_LIB_NAMEW,L"<",__WFUNCTION__,L">: ",NULL) #endif #endif //------------------------------------------------------------------------------------------------------------------------------------------
// 内部参数 #define MAX_BDGBUFF 4096 //------------------------------------------------------------------------------------------------------------------------------------------
// 计时 #ifdef __cplusplus extern "C"{ #endif LIBBASE_API ULONGLONG WINAPI GetPerformaceCount(); #ifdef __cplusplus }; #endif //------------------------------------------------------------------------------------------------------------------------------------------
// 输出工具 #ifdef __cplusplus // 对 C 代码不可见 template<class _Ty> class dbgwriter_dbg { public: void put(const _Ty* str){} }; template<class _Ty>
class dbgwriter_con { public: void put(const _Ty* str){} }; template<>
void dbgwriter_dbg<CHAR>::put(const CHAR* str) { OutputDebugStringA(str); } template<>
void dbgwriter_dbg<WCHAR>::put(const WCHAR* str) { OutputDebugStringW(str); } template<>
void dbgwriter_con<CHAR>::put(const CHAR* str) { HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); if (hStdOut != INVALID_HANDLE_VALUE) { DWORD dwRet; WriteConsoleA(hStdOut,str,strlen(str),&dwRet,NULL); } } template<>
void dbgwriter_con<WCHAR>::put(const WCHAR* str) { HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); if (hStdOut != INVALID_HANDLE_VALUE) { DWORD dwRet; WriteConsoleW(hStdOut,str,wcslen(str),&dwRet,NULL); } } typedef dbgwriter_con<CHAR> dbgwriter_conA;
typedef dbgwriter_con<WCHAR> dbgwriter_conW; typedef dbgwriter_dbg<CHAR> dbgwriter_dbgA;
typedef dbgwriter_dbg<WCHAR> dbgwriter_dbgW; #endif //------------------------------------------------------------------------------------------------------------------------------------------ // 行调试 #ifdef __cplusplus extern "C"{ #endif typedef void (WINAPI* PFNDBGPRINT_DBGA)(LPCSTR str, ...); typedef void (WINAPI* PFNDBGPRINT_DBGW)(LPCWSTR str, ...); typedef void (WINAPI* PFNDBGPRINT_CONA)(LPCSTR str, ...); typedef void (WINAPI* PFNDBGPRINT_CONW)(LPCWSTR str, ...); typedef void (WINAPI* PFNDBGPRINTV_DBGA)(LPCSTR ptzFormat, va_list vlArgs); typedef void (WINAPI* PFNDBGPRINTV_DBGW)(LPCWSTR ptzFormat, va_list vlArgs); typedef void (WINAPI* PFNDBGPRINTV_CONA)(LPCSTR ptzFormat, va_list vlArgs); typedef void (WINAPI* PFNDBGPRINTV_CONW)(LPCWSTR ptzFormat, va_list vlArgs); LIBBASE_API PFNDBGPRINT_DBGA WINAPI _DbgPrint_DBGA(LPCSTR pszTag); LIBBASE_API PFNDBGPRINT_DBGW WINAPI _DbgPrint_DBGW(LPCWSTR pszTag); LIBBASE_API PFNDBGPRINT_CONA WINAPI _DbgPrint_CONA(LPCSTR pszTag); LIBBASE_API PFNDBGPRINT_CONW WINAPI _DbgPrint_CONW(LPCWSTR pszTag); LIBBASE_API PFNDBGPRINTV_DBGA WINAPI _DbgPrintV_DBGA(LPCSTR pszTag); LIBBASE_API PFNDBGPRINTV_DBGW WINAPI _DbgPrintV_DBGW(LPCWSTR pszTag); LIBBASE_API PFNDBGPRINTV_CONA WINAPI _DbgPrintV_CONA(LPCSTR pszTag); LIBBASE_API PFNDBGPRINTV_CONW WINAPI _DbgPrintV_CONW(LPCWSTR pszTag); #ifdef __cplusplus }; #endif #define DbgPrint_CONA _DbgPrint_CONA(DEF_LOC_STDOUT_A)
#define DbgPrint_CONW _DbgPrint_CONW(DEF_LOC_STDOUT_W) #define DbgPrint_DBGA _DbgPrint_DBGA(DEF_LOC_STDOUT_A) #define DbgPrint_DBGW _DbgPrint_DBGW(DEF_LOC_STDOUT_W) #define DbgPrintV_CONA _DbgPrintV_CONA(DEF_LOC_STDOUT_A) #define DbgPrintV_CONW _DbgPrintV_CONW(DEF_LOC_STDOUT_W) #define DbgPrintV_DBGA _DbgPrintV_DBGA(DEF_LOC_STDOUT_A) #define DbgPrintV_DBGW _DbgPrintV_DBGW(DEF_LOC_STDOUT_W) #ifdef _UNICODE
#define DbgPrint_CON DbgPrint_CONW #define DbgPrint_DBG DbgPrint_DBGW #define DbgPrintV_CON DbgPrintV_CONW #define DbgPrintV_DBG DbgPrintV_DBGW #else #define DbgPrint_CON DbgPrint_CONA #define DbgPrint_DBG DbgPrint_DBGA #define DbgPrintV_CON DbgPrintV_CONA #define DbgPrintV_DBG DbgPrintV_DBGA #endif //------------------------------------------------------------------------------------------------------------------------------------------
//函数过程追踪 #ifdef __cplusplus // 对 C 代码不可见 template <class _Wy> class DBGFUNCTRACE { protected: CStdString m_strTag;//必须保存原始字符串,而不是指针,因为可能对方是临时内存块 ULONGLONG dwEnter; public: DBGFUNCTRACE(LPCTSTR pszTag) { m_strTag=pszTag?pszTag:_T(""); CStdString _str; _str.Format(_T("%s++\n"),m_strTag.c_str()); _Wy().put(_str.c_str()); dwEnter = GetPerformaceCount();
} ~DBGFUNCTRACE() { CStdString _str; _str.Format(_T("%s--,Escaped:%lu\n"),m_strTag.c_str(),GetPerformaceCount() - dwEnter); _Wy().put(_str.c_str()); } }; #ifdef _UNICODE
#define _TRACE_FUNCTION_CON() DBGFUNCTRACE<dbgwriter_conW> _FuncTrace ## __LINE__(DEF_LOC_STDOUT_W); #define _TRACE_FUNCTION_DBG() DBGFUNCTRACE<dbgwriter_dbgW> _FuncTrace ## __LINE__(DEF_LOC_STDOUT_W); #else #define _TRACE_FUNCTION_CON() DBGFUNCTRACE<dbgwriter_conA> _FuncTrace ## __LINE__(DEF_LOC_STDOUT_A); #define _TRACE_FUNCTION_DBG() DBGFUNCTRACE<dbgwriter_dbgA> _FuncTrace ## __LINE__(DEF_LOC_STDOUT_A); #endif #else // !__cplusplus #define _TRACE_FUNCTION_CON() // C 编译方式下不支持 #define _TRACE_FUNCTION_DBG() // C 编译方式下不支持 #endif //------------------------------------------------------------------------------------------------------------------------------------------ //这是最终的映射 #if (_DBG_GLOBAL_SWITCH && ((defined(_DBG) && _DBG) || defined(_DEBUG))) #if defined(_CONSOLE) && (_DBG_FORCEDBGSTR_SWITCH==0) #define DbgPrintA DbgPrint_CONA #define DbgPrintW DbgPrint_CONW #define DbgPrintVA DbgPrintV_CONA #define DbgPrintVW DbgPrintV_CONW #define _TRACE_FUNCTION_() _TRACE_FUNCTION_CON() #else #define DbgPrintA DbgPrint_DBGA #define DbgPrintW DbgPrint_DBGW #define DbgPrintVA DbgPrintV_DBGA #define DbgPrintVW DbgPrintV_DBGW #define _TRACE_FUNCTION_() _TRACE_FUNCTION_DBG() #endif #else // DbgPrint #define DbgPrintA __noop #define DbgPrintW __noop #define DbgPrintVA __noop #define DbgPrintVW __noop #define _TRACE_FUNCTION_() #endif // DbgPrint #ifdef _UNICODE
#define DbgPrint DbgPrintW #else #define DbgPrint DbgPrintA #endif //------------------------------------------------------------------------------------------------------------------------------------------
#ifdef __cplusplus extern "C"{ #endif LIBBASE_API void WINAPI assert_breakin(const char * exp, void * file, unsigned fileno); #ifdef __cplusplus }; #endif #include <assert.h>
#include <crtdbg.h> #if _DBG_BREAKIN_ASSERT #ifdef assert #undef assert #endif #ifdef _DEBUG
#define assert(exp) (void)( (exp) || (assert_breakin(#exp, __FILE__, __LINE__), 0) ) #else #define assert(exp) ((void)0) #endif #endif #ifdef _ASSERT #undef _ASSERT #endif #ifdef ASSERT #undef ASSERT #endif #ifdef VERIFY #undef VERIFY #endif #define ASSERT(f) assert(f) #define _ASSERT(f) assert(f) #ifdef _DEBUG #define VERIFY(f) ASSERT(f) #else #define VERIFY(f) ((void)(f)) #endif 6月28日 I did not speak outFirst they came for the socialists, and I did not speak out because I was not socialist. Then they came for the trade unionists, and I did not speak out because I was not trade unionists. Then they came for the Jews, and I did not speak out because I was not Jew. Then they came for me, and there was no one left to speak for me. -- Pastor Martin Niemöller 6月24日 完成一个轻量级的高速UI库一直打算做的一件事,终于下决心行动起来并把它完成了.支持常见的格式,也支持不常见的各种bmp变形格式,支持多种加载/绘图方式,在非常追求性能的情况下,可以使用32位缓存绘图方式,速度极快. |
|
|