Link to home
Start Free TrialLog in
Avatar of deming
deming

asked on

OutputDebugString and sprintf

Wow, this has been driving me crazy for 2 days now. Please help!

I have written a DLL in C++ VS2008. I simply want to write some debug messages to the output window of the VS IDE which include text and variables. I want something like:

sprintf( "Var a = %d, var b= %d",a,b);  // Send to Output window of debugger

I found some code on EE (see below) which should work but doesn't.

QUESTION:
Tell me what is wrong with my code or simply trash my code and give me some code that will acomplish my objective.

/////////////////////////////////////////////////////////
//                                                     
//	This is example code for a simple DLL
//                                                         
/////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "string"
 
/////////////////////////////////////////////////////////
//                                                     
//	DLLMain
//                                                         
/////////////////////////////////////////////////////////
 
BOOL APIENTRY DllMain
( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
    switch ( ul_reason_for_call )
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
		break;
    }
    return TRUE ;
}
 
/****************************************************************************
* DBGprintf
*
* This debugging function prints out a string to the debug output.
* An optional set of substitutional parameters can be specified,
* and the final output will be the processed result of these combined
* with the format string, just like printf.  A newline is always
* output after every call to this function.
*
* Arguments:
*   LPTSTR fmt - Format string (printf style).
*   ...        - Variable number of arguments.
* Returns:
*    VOID
\****************************************************************************/
 
void DbgPrintf(LPTSTR fmt,...    )
{
    va_list marker;
    TCHAR szBuf[256];
 
    va_start(marker, fmt);
    wvsprintf(szBuf, fmt, marker);
    va_end(marker);
 
    OutputDebugString(szBuf);
    OutputDebugString(TEXT("\r\n"));
}
 
////////////////////////////////////////////////////////
//
//	Example code for simple test function
//
////////////////////////////////////////////////////////
int __stdcall AddThem( int a, int b )
{
	//OutputDebugString("The value of a=",a,", and b=",b, ",and myStr=",myStr);
	DbgPrintf("Just a test %d, %f ",1.23f,4.56f);
	double da = 7.89, db =90.12;
	// a=7, b=4 
	DbgPrintf("Just a test1 a= %d, b= %f ",a,b);
	DbgPrintf("Just a test2 a= %d, b= %f ",da,db);
	return a + b ;
}
 
OUTPUT:
 
Just a test -2147483648, f 
Just a test1 a= 7, b= f 
Just a test2 a= 687194767, b= f

Open in new window

Avatar of nonubik
nonubik

That's because you use the WIN32 API wvsprintf function for formatting that does not support floating point (see MSDN for wsprintf) and your %f was ignored.
Instead you should try using a run-time function, such as vsprintf:
 

void DbgPrintf(LPTSTR fmt,...    )
{
    va_list marker;
    TCHAR szBuf[256];
 
    va_start(marker, fmt);
 --->here   vsprintf(szBuf, fmt, marker);
    va_end(marker);
 
    OutputDebugString(szBuf);
    OutputDebugString(TEXT("\r\n"));
}

Open in new window

Avatar of deming

ASKER

Thank you for your feedback. I tried what you suggested using the "vsprintf" as seen in my code below. The results are still incorrect and showing as:

Just a test -2147483648, -0.000000
Just a test1 a= 7, b= 0.000000
Just a test2 a= 687194767, b= 0.000000
/////////////////////////////////////////////////////////
//                                                     
//	This is example code for a simple DLL
//                                                         
/////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "string"
 
/////////////////////////////////////////////////////////
//                                                     
//	DLLMain
//                                                         
/////////////////////////////////////////////////////////
 
BOOL APIENTRY DllMain
( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
    switch ( ul_reason_for_call )
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
		break;
    }
    return TRUE ;
}
 
/****************************************************************************
* DBGprintf
*
* This debugging function prints out a string to the debug output.
* An optional set of substitutional parameters can be specified,
* and the final output will be the processed result of these combined
* with the format string, just like printf.  A newline is always
* output after every call to this function.
*
* Arguments:
*   LPTSTR fmt - Format string (printf style).
*   ...        - Variable number of arguments.
* Returns:
*    VOID
\****************************************************************************/
 
void DbgPrintf(LPTSTR fmt,...    )
{
    va_list marker;
    char szBuf[256];
 
    va_start(marker, fmt);
    //wvsprintf(szBuf, fmt, marker);
	vsprintf(szBuf, fmt, marker);
    va_end(marker);
 
    OutputDebugString(szBuf);
    OutputDebugString(TEXT("\r\n"));
}
 
////////////////////////////////////////////////////////
//
//	Example code for simple test function
//
////////////////////////////////////////////////////////
int __stdcall AddThem( int a, int b )
{
	//OutputDebugString("The value of a=",a,", and b=",b, ",and myStr=",myStr);
	DbgPrintf("Just a test %d, %f ",1.23f,4.56f);
	double da = 7.89, db =90.12;
	a=7;
	b=4; 
	DbgPrintf("Just a test1 a= %d, b= %f ",a,b);
	DbgPrintf("Just a test2 a= %d, b= %f ",da,db);
	return a + b ;
}

Open in new window

int __stdcall AddThem( int a, int b )
{
      //OutputDebugString("The value of a=",a,", and b=",b, ",and myStr=",myStr);
      //DbgPrintf("Just a test %d, %f ",1.23f,4.56f); //because you try to pass 1.23f as a decimal, it is ignored and the result is unpredicted
-->DbgPrintf("Just a test %f, %f ",1.23f,4.56f);
      double da = 7.89, db =90.12;
      a=7;
      b=4;
      //DbgPrintf("Just a test1 a= %d, b= %f ",a,b); //here you try to pass variable b as float but it is declared as int
-->DbgPrintf("Just a test1 a= %d, b= %d ",a,b);
      //DbgPrintf("Just a test2 a= %d, b= %f ",da,db); //again, you try to pass variable da as decimal but it's declared as double
-->DbgPrintf("Just a test2 a= %lf, b= %lf ",da,db);
      return a + b ;
}
Avatar of deming

ASKER

Thank you for your help, I really appreciate it.  I modified my code per your suggestion, but am still getting crazy output. It appears that it is working with strings, and int vars, but produces crazy output for floats and doubles. Could it be some sort of compiler option?

----BEGIN A----
Hello World-A
Just a testA1 f, f
Just a testA2 a= 7, b= 4
Just a testA3 a= f, b= f
Just a testA4 a= 687194767, b= 1075810140
----END A----

/////////////////////////////////////////////////////////
//                                                     
//	This is example code for a simple DLL
//                                                         
/////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "string"
 
/////////////////////////////////////////////////////////
//                                                     
//	DLLMain
//                                                         
/////////////////////////////////////////////////////////
 
BOOL APIENTRY DllMain
( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
    switch ( ul_reason_for_call )
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
		break;
    }
    return TRUE ;
}
 
/****************************************************************************
* DBGprintf
*
* This debugging function prints out a string to the debug output.
* An optional set of substitutional parameters can be specified,
* and the final output will be the processed result of these combined
* with the format string, just like printf.  A newline is always
* output after every call to this function.
*
* Arguments:
*   LPTSTR fmt - Format string (printf style).
*   ...        - Variable number of arguments.
* Returns:
*    VOID
\****************************************************************************/
 
void DbgPrintf(LPTSTR fmt,...    )
{
    va_list marker;
    char szBuf[256];
 
    va_start(marker, fmt);
    wvsprintf(szBuf, fmt, marker);
	//vsprintf(szBuf, fmt, marker);
    va_end(marker);
 
    OutputDebugString(szBuf);
    OutputDebugString(TEXT("\r\n"));
}
 
//extern "C" void __cdecl DbgReportA      (   char*   pszFormat,  ...)
void DbgReportA(char*   pszFormat,  ...)
{
    //static  char    s_acBuf         [   DBG_REPORT_BUFSIZE];
	static char s_acBuf[512];
 
    va_list args;
    va_start(args, pszFormat);
    wvsprintf(s_acBuf, pszFormat, args);
    // ...
    va_end(args);
}
 
////////////////////////////////////////////////////////
//
//	Example code for simple test function
//
////////////////////////////////////////////////////////
int __stdcall AddThem( int a, int b )
{
	OutputDebugString("----BEGIN A----\n");
	DbgPrintf("Hello World-A ");
	DbgPrintf("Just a testA1 %f, %f ",1.23f,4.56f);
	double da = 7.89, db =90.12;
	a=7;
	b=4; 
	DbgPrintf("Just a testA2 a= %d, b= %d ",a,b);
	DbgPrintf("Just a testA3 a= %lf, b= %lf ",da,db);
	DbgPrintf("Just a testA4 a= %d, b= %d ",da,db);
	OutputDebugString("----END A----\n");
 
 //   THIS CODE WORKS but is not a function.
 //	  TCHAR szBuf[256];
 //   sprintf(szBuf, "Test-A %.3f %.3f %i \n", da, db, a);
 //   OutputDebugString(szBuf);
 
	//OutputDebugString("----BEGIN B----\n");
	//DbgReportA("Hello World-B ");
	//DbgReportA("Just a testB1 %f, %f ",1.23f,4.56f);
	//DbgReportA("Just a testB2 a= %d, b= %d ",a,b);
	//DbgReportA("Just a testB3 a= %d, b= %f ",da,db);
	//DbgReportA("Just a testB4 a= %f, b= %d ",da,db);
	//OutputDebugString("----END B----\n");
 
	return a + b ;
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of nonubik
nonubik

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of deming

ASKER

Thank you nonubik!  That fixed it and it is now working with the following output. The testA4 line is garbage because of incorrect formatting.

Where did you find the %lf format?  I have looked and didn't see that one.

----BEGIN A----
Hello World-A
Just a testA1 1.230000, 4.560000
Just a testA2 a= 7, b= 4
Just a testA3 a= 7.890000, b= 90.120000
Just a testA4 a= 687194767, b= 1075810140
----END A----
Yes, it is.
The 'lf' format is composed of 'f' from float type and the 'l' which is an argument size, because your variables are declared as double and not float.
Avatar of deming

ASKER

Thank you nonubik! Everything is working great. Just in case anyone is following along, I have posted my final working code.
/////////////////////////////////////////////////////////
//                                                     
//	This is example code for a simple DLL
//                                                         
/////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "string"
 
/////////////////////////////////////////////////////////
//                                                     
//	DLLMain
//                                                         
/////////////////////////////////////////////////////////
 
BOOL APIENTRY DllMain
( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
    switch ( ul_reason_for_call )
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
		break;
    }
    return TRUE ;
}
 
/****************************************************************************
* DBGprintf
*
* This debugging function prints out a string to the debug output.
* An optional set of substitutional parameters can be specified,
* and the final output will be the processed result of these combined
* with the format string, just like printf.  A newline is always
* output after every call to this function.
*
* Arguments:
*   LPTSTR fmt - Format string (printf style).
*   ...        - Variable number of arguments.
* Returns:
*    VOID
\****************************************************************************/
 
void DbgPrintf(LPTSTR fmt,...    )
{
    va_list marker;
    char szBuf[256];
 
    va_start(marker, fmt);
    //wvsprintf(szBuf, fmt, marker);
    //vswprintf(szBuf, fmt, marker);
	vsprintf(szBuf, fmt, marker);
	va_end(marker);
 
    OutputDebugString(szBuf);
    OutputDebugString(TEXT("\r\n"));
}
 
////////////////////////////////////////////////////////
//
//	Example code for simple test function
//
////////////////////////////////////////////////////////
int __stdcall AddThem( int a, int b )
{
	OutputDebugString("----BEGIN A----\n");
	DbgPrintf("Hello World-A ");
	DbgPrintf("Just a testA1 %f, %f ",1.23f,4.56f);
	double da = 7.89, db =90.12;
	a=7;
	b=4; 
	DbgPrintf("Just a testA2 a= %d, b= %d ",a,b);
	DbgPrintf("Just a testA3 a= %lf, b= %lf ",da,db);
	DbgPrintf("----END A----\n");
 
	return a + b ;
}

Open in new window