6

Win32アプリをコンパイルするときに、fprintf(stdout / stderr)はVisual Studioのどこに出力されますか?私はそれが出力に行くのを聞き続けます、しかし私はそれを見ることができません!。

C ++でコンソールウィンドウを使用せずに出力ログに出力する標準的な方法は何ですか?

4

1 に答える 1

15

プログラムが /SUBSYSTEM:WINDOWS とリンクされている場合、コンソールを割り当てない限り、コンソール出力は表示されません。

これは、allocate console オプションのコードです。この方法では、リンカー設定を変更したり、WinMain を作成したりする必要はありません。

static void OpenConsole()
{
    int outHandle, errHandle, inHandle;
    FILE *outFile, *errFile, *inFile;
    AllocConsole();
    CONSOLE_SCREEN_BUFFER_INFO coninfo;
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
    coninfo.dwSize.Y = 9999;
    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);

    outHandle = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
    errHandle = _open_osfhandle((long)GetStdHandle(STD_ERROR_HANDLE),_O_TEXT);
    inHandle = _open_osfhandle((long)GetStdHandle(STD_INPUT_HANDLE),_O_TEXT );

    outFile = _fdopen(outHandle, "w" );
    errFile = _fdopen(errHandle, "w");
    inFile =  _fdopen(inHandle, "r");

    *stdout = *outFile;
    *stderr = *errFile;
    *stdin = *inFile;

    setvbuf( stdout, NULL, _IONBF, 0 );
    setvbuf( stderr, NULL, _IONBF, 0 );
    setvbuf( stdin, NULL, _IONBF, 0 );

    std::ios::sync_with_stdio();

}

コンソールを直接割り当てたくない場合は、リンカー設定のサブシステムを変更して、サブシステムを /SUBSYSTEM:WINDOWS から /SUBSYSTEM:CONSOLE に変更することもできます。/SUBSYSTEM:CONSOLE が有効になっている場合、GUI は以前と同じように機能しますが、ウィンドウはアプリケーションと共にコンソール ウィンドウを作成します。

私のQtコードでは、必要なのはそれだけです。ただし、VisualStudioでMFCを試し、リンカー設定を介してサブシステムをコンソールに設定したとき。次のエラーが発生しました。

1>------ Build started: Project: MFCApplication1, Configuration: Debug Win32 ------
1>  MFCApplication1.cpp
1>msvcrtd.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
1>X:\Test\VC.110\MFCTest\MFCApplication1\Debug\MFCApplication1.exe : fatal error LNK1120: 1 unresolved externals

これは、エントリ ポイントがコンソール アプリケーションでは main() にデフォルト設定され、Windows アプリケーションでは WinMain にデフォルト設定されていることが原因です。これを修正するには、Advanced Linker 設定の Entry Point 設定に以下を追加する必要がありました: "wWinMainCRTStartup"

コメントで、Ben Voigt は別の方法を提案しました。editbin を使用してサブシステムを変更する場合、エントリ ポイントを変更する必要はありません。これは実際にそうです。エントリ ポイントを削除し、サブシステムがテスト アプリケーションをビルドしたときにウィンドウを元に戻し、次のコマンドを使用して editbin を使用してサブシステムを変更しました。

X:\Test\VC.110\MFCTest\MFCApplication1\Debug>editbin MFCApplication1.exe /SUBSYSTEM:CONSOLE
Microsoft (R) COFF/PE Editor Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

そして、コンソールに期待どおりの出力が得られました。

X:\Test\VC.110\MFCTest\MFCApplication1\Debug>MFCApplication1.exe
Hello from a windows application!
 

注: editbin メソッドでは、実行可能ファイルを更新するたびにこれを有効にする必要があります。

最後に、コンソールの printf または std::cout を取得すると、どちらの方法でも機能します。たとえば、私のテスト MFC アプリケーションでは、次の行を CMFCApplication1App クラスのコンストラクターに追加しました。

std::cout << "Hello from a windows application!" << std::endl;
于 2012-12-12T14:04:33.523 に答える