web-dev-qa-db-ja.com

Win32アプリのデバッグ出力ウィンドウに印刷するにはどうすればよいですか?

Visual Studio 2005に読み込んだwin32プロジェクトがあります。VisualStudioの出力ウィンドウに印刷できるようにしたいと思いますが、私の人生ではどうすればよいかわかりません。 「printf」と「cout <<」を試しましたが、私のメッセージは頑固に印刷されません。

Visual Studioの出力ウィンドウに印刷する特別な方法はありますか?

85
izb

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.");
127

プロジェクトがGUIプロジェクトの場合、コンソールは表示されません。プロジェクトをコンソールに変更するには、プロジェクトプロパティパネルに移動して設定する必要があります。

  • リンカー->システム->サブシステム」値「コンソール(/ SUBSYSTEM:CONSOLE)
  • C/C++-> Preprocessor-> Preprocessor Definitions」に「_ CONSOLE

このソリューションは、古典的な「int main()」エントリポイントがある場合にのみ機能します。

ただし、私の場合(openGLプロジェクト)の場合、プロパティを編集する必要はありません。

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

printfとcoutは通常どおり動作します。

ウィンドウを作成する前にAllocConsoleを呼び出すと、コンソールはウィンドウの背後に表示され、後で呼び出すと、コンソールが前方に表示されます。

27
Zac

realコンソールに出力するには、リンカーフラグ/SUBSYSTEM:CONSOLEを使用して表示できるようにする必要があります。余分なコンソールウィンドウは迷惑ですが、デバッグの目的には非常に貴重です。

OutputDebugStringは、デバッガー内で実行しているときにデバッガーの出力に出力します。

12
Ringding

コードを変更せずに(または最小限の変更で)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__)
4
vlad

レポート用のVC++ランタイムマクロの使用を検討してください _ RPTN()および_RPTFN()

CRTDBG.Hで定義されている_RPTnおよび_RPTFnマクロを使用して、デバッグ用の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デバッガー)、またはデバッグメッセージウィンドウの3つの異なる宛先にデバッグレポートを送信できます。

_CrtDbgReportおよび_CrtDbgReportWは、printfまたはwprintf関数で定義されているのと同じルールを使用して、argument [n]引数をフォーマット文字列に置き換えることにより、デバッグレポートのユーザーメッセージを作成します。これらの関数は、デバッグレポートを生成し、現在のレポートモードとreportTypeに定義されたファイルに基づいて、1つまたは複数の宛先を決定します。レポートがデバッグメッセージウィンドウに送信されると、ファイル名、lineNumber、およびmoduleNameがウィンドウに表示される情報に含まれます。

4
Autodidact

10進変数を出力する場合:

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

Win32プロジェクトはおそらくコンソールプロジェクトではなくGUIプロジェクトです。これにより、実行可能ヘッダーに違いが生じます。その結果、GUIプロジェクトは独自のウィンドウを開くことになります。ただし、コンソールウィンドウの場合があります。 AllocConsole()を呼び出して作成し、Win32コンソール関数を使用して書き込みます。

2
MSalters

私は自分でこれを行う方法を探していて、簡単な解決策を見つけました。

「WinMain」機能を提供するVisual StudioでデフォルトのWin32プロジェクト(Windowsアプリケーション)を開始したと仮定しています。デフォルトでは、Visual Studioはエントリポイントを「SUBSYSTEM:WINDOWS」に設定します。最初にこれを変更する必要があります:

プロジェクト->プロパティ->リンカー->システム->サブシステム

そして、ドロップダウンリストから「コンソール(/ SUBSYSTEM:CONSOLE)」を選択します。

「WinMain」関数の代わりに「main」関数が必要なため、プログラムは実行されません。

したがって、C++で通常行うように「メイン」関数を追加できます。この後、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プログラムの任意の部分のコンソールに出力できます。

2
pops

WriteConsoleメソッドを使用してコンソールに印刷することもできます。

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