Pregunta ¿Cómo imprimo en la ventana de salida de depuración en una aplicación Win32?


Tengo un proyecto de win32 que cargué en Visual Studio 2005. Me gustaría poder imprimir cosas en la ventana de salida de Visual Studio, pero no puedo averiguar cómo. He intentado con 'printf' y 'cout <<', pero mis mensajes siguen siendo obstinadamente no impresos.

¿Hay algún tipo de forma especial de imprimir en la ventana de salida de Visual Studio?


73
2017-08-26 09:45


origen


Respuestas:


Puedes usar OutputDebugString. OutputDebugString es una macro que dependiendo de tus opciones de compilación se asigna a OutputDebugStringA(char const*) o OutputDebugStringW(wchar_t const*). En el caso posterior, deberá proporcionar una cadena de caracteres amplia a la función. Para crear un literal de caracteres anchos, puede usar L prefijo:

OutputDebugStringW(L"My output string.");

Normalmente usará la versión de macro junto con el _T macro como esta:

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

Si el proyecto está configurado para compilar para UNICODE, se expandirá a:

OutputDebugStringW(L"My output string.");

Si no está compilando para UNICODE, se expandirá a:

OutputDebugStringA("My output string.");

111
2017-08-26 09:50



Si el proyecto es un proyecto de GUI, no aparecerá ninguna consola. Para cambiar el proyecto a consola, debe ir al panel de propiedades del proyecto y configurarlo:

  • En "enlazador-> Sistema-> SubSistema" el valor "Consola (/ SUBSISTEMA: CONSOLA)"
  • En "C / C ++ -> Preprocesador-> Definiciones del preprocesador" añade el "_CONSOLA"definir

Esta solución solo funciona si tienes el clásico "int main ()" punto de entrada.

Pero si usted es como en mi caso (un proyecto de OpenGL), no necesita editar las propiedades, ya que esto funciona mejor:

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

printf y cout funcionarán como de costumbre.

Si llama a AllocConsole antes de la creación de una ventana, la consola aparecerá detrás de la ventana, si la llama después, aparecerá más adelante.


26
2017-10-16 14:53



Para imprimir al real consola, debe hacerla visible utilizando la bandera del enlazador /SUBSYSTEM:CONSOLE. La ventana extra de la consola es molesta, pero para fines de depuración es muy valiosa.

OutputDebugString imprime en la salida del depurador cuando se ejecuta dentro del depurador.


12
2017-08-26 09:52



Considere usar las macros de tiempo de ejecución de VC ++ para generar informes _RPTnorte() y _RPTFnorte()

Puede usar las macros _RPTn y _RPTFn, definidas en CRTDBG.H, para   reemplace el uso de instrucciones printf para la depuración. Estas macros   desaparecerá automáticamente en su compilación de lanzamiento cuando _DEBUG no sea   definido, por lo que no es necesario incluirlos en #ifdefs.

Ejemplo...

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

O puede usar las funciones de tiempo de ejecución de VC ++ _CrtDbgReport, _CrtDbgReportW directamente.

_CrtDbgReport y _CrtDbgReportW pueden enviar el informe de depuración a tres destinos diferentes: un archivo de informe de depuración, un monitor de depuración (el   Depurador de Visual Studio), o una ventana de mensaje de depuración.

_CrtDbgReport y _CrtDbgReportW crean el mensaje de usuario para el informe de depuración sustituyendo los argumentos del argumento [n] por el formato   cadena, usando las mismas reglas definidas por printf o wprintf   funciones. Estas funciones luego generan el informe de depuración y   determinar el destino o los destinos, de acuerdo con el informe actual   modos y archivo definidos para reportType. Cuando el informe se envía a un   ventana de mensaje de depuración, el nombre de archivo, lineNumber y moduleName son   incluido en la información que se muestra en la ventana.


3
2018-03-09 12:24



Su proyecto Win32 probablemente sea un proyecto GUI, no un proyecto de consola. Esto causa una diferencia en el encabezado ejecutable. Como resultado, su proyecto de GUI será responsable de abrir su propia ventana. Sin embargo, puede ser una ventana de consola. Llamada AllocConsole() para crearlo, y usar las funciones de la consola Win32 para escribir en él.


2
2017-08-26 09:54



Si desea imprimir variables decimales:

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

2
2017-11-09 21:16



Si necesita ver el resultado de un programa existente que usaba printf sin cambiar el código (o con cambios mínimos), puede redefinir printf de la siguiente manera y agregarlo al encabezado común (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__)

1
2017-08-18 19:53



También puedes usar WriteConsole método para imprimir en la consola.

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

1
2018-04-07 21:53



Estaba buscando una forma de hacerlo yo mismo y descubrí una solución simple.

Supongo que comenzó un Proyecto Win32 predeterminado (aplicación Windows) en Visual Studio, que proporciona una función "WinMain". De forma predeterminada, Visual Studio establece el punto de entrada en "SUBSISTEMA: WINDOWS". Primero debe cambiar esto yendo a:

Proyecto -> Propiedades -> Enlazador -> Sistema -> Subsistema

Y seleccione "Consola (/ SUBSISTEMA: CONSOLA)" en la lista desplegable.

Ahora, el programa no se ejecutará, ya que se necesita una función "principal" en lugar de la función "WinMain".

Entonces ahora puede agregar una función "principal" como lo haría normalmente en C ++. Después de esto, para iniciar el programa GUI, puede llamar a la función "WinMain" desde dentro de la función "principal".

La parte inicial de su programa debería verse ahora de la siguiente manera:

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

Resultado de mi implementación

Ahora puede usar las funciones para enviarlas a la consola en cualquier parte de su programa GUI para la depuración u otros fines.


0
2017-10-02 21:43