该文档参考了以下网友的文章,在此表示感谢。
1. (更新)OutputDebugString函数简单封装,实现格式化打印输出(VC++)
链接:http://blog.csdn.net/sunflover454/article/details/48718409
2. __VA_ARGS__用法(转)
链接:http://blog.chinaunix.net/uid-22878837-id-2110544.html
在VC中,有时候为了方便软件的调试,需要在软件代码中加入一些调试信息来跟踪软件的执行流程和状态,这些信息通常使用打印函数打印到调试界面上。我这边使用的调试信息查看工具是DebugView,打印信息函数使用OutputDebugStringA(对于ASCII码)或OutputDebugStringW(对于UNICODE编码)。
软件中的调试信息一般在软件的DEBUG版本中使用,在Release版本中需要将其去除。为了方便软件管理和共用代码,最好自己定义调试信息打印函数,然后通过宏定义来控制是否需要打印信息。这里参照前面的文章1,对其代码进行了一些修改,方便自己的使用。调试信息打印函数的实现代码单独放在MyOutputDebugString.cpp文件中,在MyOutputDebugString.h头文件中进行了调试信息打印函数的声明,同时通过_DEBUG宏定义来控制是否在软件中包含调试信息。实际使用时,只需将这2个文件包含到工程中,然后包含MyOutputDebugString.h头文件即可。
具体代码如下。
MyOutputDebugString.h头文件代码。
#pragma once #if _DEBUG #define DEBUG_INFO(...) MyOutputDebugStringW(__VA_ARGS__) #else #define DEBUG_INFO(...) #endif // ASCII码形式的打印信息函数,lpcszFilterString为DebugView的过滤字符串,lpcszOutputString为格式化输出字符 // 使用示例:MyOutputDebugStringA("DLL: ","%d,%s",123,"hello"); void MyOutputDebugStringA(const char * lpcszFilterString, const char * lpcszOutputString, ...); // UNICODE码形式的打印信息函数,lpcszFilterString为DebugView的过滤字符串,lpcszOutputString为格式化输出字符 // 使用示例:MyOutputDebugStringW(L"DLL: ",L"%d,%s",456,L"world!"); void MyOutputDebugStringW(const wchar_t * lpcszFilterString, const wchar_t * szOutputString, ...);
MyOutputDebugString.cpp文件代码。
#include <windows.h> #include <stdlib.h> #include <stdarg.h> #include <vector> #include "MyOutputDebugString.h" using namespace std; void MyOutputDebugStringA(const char * lpcszFilterString, const char * lpcszOutputString, ...) { string strResult; if (NULL != lpcszOutputString) { va_list marker = NULL; va_start(marker, lpcszOutputString); //初始化变量参数 size_t nLength = _vscprintf(lpcszOutputString, marker) + 1; //获取格式化字符串长度 std::vector<char> vBuffer(nLength, '\0'); //创建用于存储格式化字符串的字符数组 int nWritten = _vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, lpcszOutputString, marker); if (nWritten>0) { strResult = &vBuffer[0]; } va_end(marker); //重置变量参数 } if (!strResult.empty()) { string strFormated = lpcszFilterString; strFormated.append(strResult); OutputDebugStringA(strFormated.c_str()); } } void MyOutputDebugStringW(const wchar_t * lpcszFilterString, const wchar_t * lpcwszOutputString, ...) { wstring strResult; if (NULL != lpcwszOutputString) { va_list marker = NULL; va_start(marker, lpcwszOutputString); //初始化变量参数 size_t nLength = _vscwprintf(lpcwszOutputString, marker) + 1; //获取格式化字符串长度 std::vector<wchar_t> vBuffer(nLength, '\0'); //创建用于存储格式化字符串的字符数组 int nWritten = _vsnwprintf_s(&vBuffer[0], vBuffer.size(), nLength, lpcwszOutputString, marker); if (nWritten>0) { strResult = &vBuffer[0]; } va_end(marker); //重置变量参数 } if (!strResult.empty()) { wstring strFormated = lpcszFilterString; strFormated.append(strResult); OutputDebugStringW(strFormated.c_str()); } }
以上代码中的MyOutputDebugStringA为ASCII码版本,MyOutputDebugStringW为UNICODE版本。示例中DEBUG_INFO(...)定义成MyOutputDebugStringW,为UNICODE版本。如果需要使用ASCII码版本,则使用MyOutputDebugStringA即可。
对于打印文件名和函数名等的相关信息,如果使用ASCII码版本,则使用__FILE__和__FUNCTION__;如果使用UNICODE码版本,则使用__FILEW__和__FUNCTIONW__。