改良 OutputDebugString 使之可以像 printf 一样支持参数打印

在写服务程序、注入的DLL 或内核程序时,并不是很方便进行源码级的断点调试,所以有时候我们会直接在控制台打印日志信息,一些JAVA 程序员也有使用 System.out.println( "*****" )  打印执行步骤的习惯;

我在采用 printf 打印时通常都会加上详细的参数;c 标准的 printf 也支持 fromt 格式化输出:比如  printf(  "%d %s %x" ,i ,str, xn   );  这样的输出方式可以让我更清晰的看到当前需要查看的值;

但是 printf 不是在所有的地方都能用,比如 Win32 应用程序、MFC 以及 DLL  中 就不可以了,微软为之提供了专门输出方法 OutputDebugString 

MSDN:

https://docs.microsoft.com/zh-cn/windows/win32/api/debugapi/nf-debugapi-outputdebugstringa


OutputDebugString  是系统API , 我们可以自己的程序代码加入自己的调试信息,与printf 不一样 ,它的输出信息需要我们使用专门的工具查看,这个工具叫 DebugView 也是微软提供的;

但是 OutputDebugString 有一点不方便的是,他没有你 printf 一样可以支持 format 格式化参数输出,它默认只能输出 一个字符串,如果我们想同时打印多个不同类型的值,就只能自己拼接好了,再传进去了;

之前抽了点时间 写了个 2 方法,通过可变长参数来接受 format 的格式化输出,可以像调用 printf 一样将自己想输出多个不同类型的参数一起打印出来;


关键知识点:

va_list argptr;

va_start(argptr, format);

.....

va_end(argptr);


void OutputDebugStringA2(CHAR * format, ...)
{
	va_list argptr;
	va_start(argptr, format);

 	size_t ACTSIZE = _vscprintf(format, argptr);
	char*buffer = (char*)malloc(ACTSIZE + 1);
	memset(buffer, 0, ACTSIZE + 1);
	vsnprintf(buffer, ACTSIZE + 1, format, argptr);
 
	va_end(argptr);

 	OutputDebugStringA(buffer);

	free(buffer);
	buffer = nullptr;

}


void OutputDebugStringW2(WCHAR * format, ...)
{
	va_list argptr;
	va_start(argptr, format);

	size_t ACTSIZE = _vscwprintf(format, argptr);
	WCHAR *buffer = new WCHAR[ACTSIZE+1];//(WCHAR*)malloc(ACTSIZE  );
	memset(buffer, '\0', ACTSIZE+1 );
	_vsnwprintf(buffer, ACTSIZE +1 , format, argptr);
 
	va_end(argptr);

	OutputDebugStringW(buffer);
	//delete buffer;
	free(buffer);
	buffer = nullptr;
}