如何打印到Win32应用程序的debugging输出窗口?

我有一个win32项目,我已经加载到Visual Studio 2005.我想能够打印的东西到Visual Studio输出窗口,但我不能为我的生活工作如何。 我已经尝试过“printf”和“cout <<”,但是我的信息仍然固执地不印。

是否有某种特殊的方式来打印到Visual Studio输出窗口?

你可以使用OutputDebugStringOutputDebugString是一个macros,根据你的构build选项,映射到OutputDebugStringA(char const*)OutputDebugStringW(wchar_t const*) 。 在后面的情况下,你将不得不提供一个宽字符的string的function。 要创build宽字符,可以使用L前缀:

 OutputDebugStringW(L"My output string."); 

通常你会像这样使用macros版本和_Tmacros:

 OutputDebugString(_T("My output string.")); 

如果你的项目configuration为为UNICODE构build,它将扩展为:

 OutputDebugStringW(L"My output string."); 

如果你不是为UNICODE构build,它将扩展到:

 OutputDebugStringA("My output string."); 

如果该项目是一个GUI项目,则不会出现控制台。 为了将项目更改为控制台,您需要转到项目属性面板并设置:

  • 在“链接器 – >系统 – >子系统 ”中,“ Console(/ SUBSYSTEM:CONSOLE)
  • 在“ C / C ++ – >预处理器 – >预处理器定义 ”中添加“ _CONSOLE ”定义

这个解决scheme只有当你有经典的“ int main() ”入口点时才起作用。

但是,如果你像我的情况(一个openGL项目),你不需要编辑的属性,因为这个效果更好:

 AllocConsole(); freopen("CONIN$", "r",stdin); freopen("CONOUT$", "w",stdout); freopen("CONOUT$", "w",stderr); 

printf和cout将照常工作。

如果在创build窗口之前调用AllocConsole,则控制台将显示在窗口后面,如果您在后面调用它,它将显示在前面。

要打印到real控制台,您需要使用连接器标志/SUBSYSTEM:CONSOLE来使其可见。 额外的控制台窗口是烦人的,但出于debugging的目的,这是非常有价值的。

OutputDebugString在debugging器中运行时打印到debugging器输出。

您的Win32项目可能是一个GUI项目,而不是一个控制台项目。 这会导致可执行头部的差异。 因此,您的GUI项目将负责打开自己的窗口。 不过,这可能是一个控制台窗口。 调用AllocConsole()来创build它,并使用Win32控制台函数来写入它。

考虑将VC ++运行时macros用于报告_RPT N ()和_RPTF N ()

您可以使用CRTDBG.H中定义的_RPTn和_RPTFnmacrosreplaceprintf语句的使用以进行debugging。 当_DEBUG未定义时,这些macros会在发布版本中自动消失,因此不需要将它们放在#ifdefs中。

例…

 if (someVar > MAX_SOMEVAR) { _RPTF2(_CRT_WARN, "In NameOfThisFunc( )," " someVar= %d, otherVar= %d\n", someVar, otherVar ); } 

或者,您可以直接使用VC ++运行时函数_CrtDbgReport,_CrtDbgReportW 。

_CrtDbgReport和_CrtDbgReportW可以将debugging报告发送到三个不同的目标:debugging报告文件,debugging监视器(Visual Studiodebugging器)或debugging消息窗口。

_CrtDbgReport和_CrtDbgReportW通过使用由printf或wprintf函数定义的相同规则将参数[n]参数replace为格式string来为debugging报告创build用户消息。 然后,这些函数将生成debugging报告,并根据为reportType定义的当前报告模式和文件确定目标或目标。 将报告发送到debugging消息窗口时,窗口中显示的信息中将包含文件名,行号和模块名称。

如果你想打印十进制variables:

 wchar_t text_buffer[20] = { 0 }; //temporary buffer swprintf(text_buffer, _countof(text_buffer), L"%d", your.variable); // convert OutputDebugString(text_buffer); // print 

如果您需要查看广泛使用printf的现有程序的输出,而无需更改代码(或只需要很less的更改),则可以按照以下方式重新定义printf,并将其添加到公共头(stdafx.h)中。

 int print_log(const char* format, ...) { static char s_printf_buf[1024]; va_list args; va_start(args, format); _vsnprintf(s_printf_buf, sizeof(s_printf_buf), format, args); va_end(args); OutputDebugStringA(s_printf_buf); return 0; } #define printf(format, ...) \ print_log(format, __VA_ARGS__) 

我正在寻找一种方法来做到这一点,并找出一个简单的解决scheme。

我假设你在Visual Studio中启动了一个默认的Win32项目(Windows应用程序),它提供了一个“WinMain”函数。 默认情况下,Visual Studio将入口点设置为“SUBSYSTEM:WINDOWS”。 你需要首先改变这个:

项目 – >属性 – >链接器 – >系统 – >子系统

然后从下拉列表中select“控制台(/ SUBSYSTEM:CONSOLE)”。

现在,程序将不会运行,因为需要“主”function而不是“WinMain”function。

所以现在你可以像在C ++中一样添加一个“main”函数。 之后,要启动GUI程序,可以在“main”函数中调用“WinMain”函数。

你的程序的起始部分现在应该看起来像这样:

 #include <iostream> using namespace std; // Main function for the console int main(){ // Calling the wWinMain function to start the GUI program // Parameters: // GetModuleHandle(NULL) - To get a handle to the current instance // NULL - Previous instance is not needed // NULL - Command line parameters are not needed // 1 - To show the window normally wWinMain(GetModuleHandle(NULL), NULL,NULL, 1); system("pause"); return 0; } // Function for entry into GUI program int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { // This will display "Hello World" in the console as soon as the GUI begins. cout << "Hello World" << endl; . . . 

我执行的结果

现在,您可以使用函数在GUI程序的任何部分输出到控制台,以进行debugging或其他目的。