Как распечатать в окне вывода отладки в приложении Win32? - PullRequest
81 голосов
/ 26 августа 2009

У меня есть проект win32, который я загрузил в Visual Studio 2005. Я хотел бы иметь возможность печатать вещи в окне вывода Visual Studio, но я не могу на всю жизнь понять, как , Я пытался «Printf» и «<<» COUT но мои сообщения остаются упорно без печати. ​​</p>

Есть ли какой-то особый способ печати в окне вывода Visual Studio?

Ответы [ 9 ]

123 голосов
/ 26 августа 2009

Вы можете использовать OutputDebugString. OutputDebugString - это макрос, который в зависимости от ваших параметров компоновки либо отображается на OutputDebugStringA(char const*), либо OutputDebugStringW(wchar_t const*). В последнем случае вам нужно будет предоставить строку широких символов для функции. Для создания литерала широких символов вы можете использовать префикс L:

OutputDebugStringW(L"My output string.");

Обычно вы будете использовать версию макроса вместе с макросом _T следующим образом:

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

Если ваш проект настроен на сборку для UNICODE, он расширится до:

OutputDebugStringW(L"My output string.");

Если вы не строите для UNICODE, он расширится до:

OutputDebugStringA("My output string.");
27 голосов
/ 16 октября 2013

Если проект является проектом с графическим интерфейсом, консоль не появится. Чтобы превратить проект в консольный, вам нужно перейти на панель свойств проекта и установить:

  • В " компоновщик-> Система-> Подсистема " значение " Консоль (/ SUBSYSTEM: CONSOLE) "
  • В " C / C ++ -> Препроцессор-> Определения препроцессора " добавить " _CONSOLE " define

Это решение работает, только если у вас была классическая точка входа " int main () ".

Но если вы похожи на мой случай (проект openGL), вам не нужно редактировать свойства, так как это работает лучше:

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

printf и cout будут работать как обычно.

Если вы вызываете AllocConsole до создания окна, консоль появится за окном, если вы вызовете ее после, она появится впереди.

12 голосов
/ 26 августа 2009

Для печати на консоль real необходимо сделать ее видимой, используя флаг компоновщика /SUBSYSTEM:CONSOLE. Дополнительное окно консоли раздражает, но для целей отладки оно очень ценно.

OutputDebugString печатает на выходе отладчика при работе внутри отладчика.

4 голосов
/ 18 августа 2016

Если вам нужно увидеть выходные данные существующей программы, которая широко использовала printf без изменения кода (или с минимальными изменениями), вы можете переопределить 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__)
3 голосов
/ 10 ноября 2015

Если вы хотите вывести десятичные переменные:

wchar_t text_buffer[20] = { 0 }; //temporary buffer
swprintf(text_buffer, _countof(text_buffer), L"%d", your.variable); // convert
OutputDebugString(text_buffer); // print
3 голосов
/ 09 марта 2015

Рассмотрите возможность использования макросов среды выполнения VC ++ для создания отчетов _RPT N () и _RPTF N ()

Вы можете использовать макросы _RPTn и _RPTFn, определенные в CRTDBG.H, чтобы замените использование операторов printf для отладки. Эти макросы автоматически исчезает в вашей сборке релиза, когда _DEBUG не определены, поэтому нет необходимости заключать их в # ifdefs.

Пример ...

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

Или вы можете использовать функции времени выполнения VC ++ _CrtDbgReport, _CrtDbgReportW напрямую.

_CrtDbgReport и _CrtDbgReportW могут отправлять отчет об отладке по трем различным адресатам: файл отчета об отладке, монитор отладки ( Отладчик Visual Studio) или окно сообщения отладки.

_CrtDbgReport и _CrtDbgReportW создают сообщение пользователя для отчета об отладке, подставляя аргументы аргумента [n] в формат строка, используя те же правила, которые определены в printf или wprintf функции. Эти функции затем генерируют отчет об отладке и определить пункт назначения или пункты назначения на основе текущего отчета режимы и файл, определенные для reportType. Когда отчет отправляется Окно сообщения отладки, имя файла, lineNumber и moduleName включены в информацию, отображаемую в окне.

2 голосов
/ 03 октября 2016

Я искал способ сделать это сам и придумал простое решение.

Я предполагаю, что вы запустили проект Win32 по умолчанию (приложение Windows) в Visual Studio, который предоставляет функцию «WinMain». По умолчанию Visual Studio устанавливает точку входа «SUBSYSTEM: WINDOWS». Вы должны сначала изменить это, перейдя на:

Проект -> Свойства -> Компоновщик -> Система -> Подсистема

И выберите «Консоль (/ SUBSYSTEM: CONSOLE)» из выпадающего списка.

Теперь программа не будет запускаться, поскольку вместо функции «WinMain» необходима «основная» функция.

Так что теперь вы можете добавить «основную» функцию, как это обычно делается в C ++. После этого, чтобы запустить программу с графическим интерфейсом, вы можете вызвать функцию «WinMain» из функции «main».

Начальная часть вашей программы должна выглядеть примерно так:

#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;
.
.
.

Результат моей реализации

Теперь вы можете использовать функции для вывода на консоль в любой части вашей программы с графическим интерфейсом для отладки или других целей.

2 голосов
/ 26 августа 2009

Ваш проект Win32, скорее всего, проект с графическим интерфейсом, а не консольный проект. Это вызывает разницу в исполняемом заголовке. В результате ваш GUI-проект будет отвечать за открытие своего собственного окна. Это может быть консольное окно, хотя. Вызовите AllocConsole() для его создания и используйте функции консоли Win32 для его записи.

1 голос
/ 08 апреля 2018

Вы также можете использовать метод WriteConsole для печати на консоли.

AllocConsole();
LPSTR lpBuff = "Hello Win32 API";
DWORD dwSize = 0;
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), lpBuff, lstrlen(lpBuff), &dwSize, NULL);
...