VC中自定义打印调试信息函数,打印调试信息到DebugView上

时间:2023-01-05 03:29:17

该文档参考了以下网友的文章,在此表示感谢。

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__。