Как распечатать в окне вывода отладки в приложении Win32?

У меня есть проект win32, который я загрузил в Visual Studio 2005. Я хочу, чтобы иметь возможность печатать вещи в окне вывода Visual Studio, но я не могу в течение всей жизни понять, как, Я пробовал 'printf' и 'cout < < но мои сообщения остаются упрямо незапечатанными.

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

Ответ 1

Вы можете использовать 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.");

Ответ 2

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

  • В "linker- > System- > SubSystem" значение "Консоль (/SUBSYSTEM: CONSOLE)"
  • В "C/С++ → Preprocessor- > Определения препроцессора" добавьте опцию "_CONSOLE"

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

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

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

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

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

Ответ 3

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

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

Ответ 4

Рассмотрим использование макросов времени выполнения VС++ для отчетов _ 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 );
}

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

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

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

Ответ 8

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

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

Проект → Свойства → Коннектор → Система → Подсистема

И выберите "Консоль (/SUBSYSTEM: CONSOLE)" в раскрывающемся списке.

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

Итак, теперь вы можете добавить "главную" функцию, как обычно, на С++. После этого, чтобы запустить программу GUI, вы можете вызвать функцию "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-программы для отладки или других целей.

Ответ 9

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

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