none
2010でのOutputDebugStringについて

    質問

  • Visual C++ 2010 Expressで開発を行っています。

    デバッグ情報の出力をOutputDebugString()で行っているのですが、出力・イミディエイトウィンドウ・DebugViewすべてに出力されず困っています。

    もちろん出力に関連するコードも、出力する文字列もデバッガ上では動作していることを確認済みです。

    ・"オプション"-"デバッガ"-"全般"-"出力ウィンドウの文字をすべてイミディエイト・・・・"をON/OFFしても、出力ウィンドウ・イミディエイトウィンドウには出力されない。

    ・_RPT0系の出力関数でも同様に出力されない。

    ・出力ウィンドウを右クリックして"プログラム出力"もON済み

    という状況で困っております。

    先駆者の方々、対処方法をお教えください。

    2017年9月10日 8:37

回答

  • 「Windowsフォームアプリケーション」というキーワードが気になりました。C++/CLIをお使いでしょうか。

    Windowsには.NET Framework上で動作するManaged環境と.NET Frameworkを使用しないNative環境の2種類が存在します。デバッガーは双方をサポートしていますが通常、その両方を必要とすることは稀なため、どちらか一方のみが有効化されます。具体的には.NET Frameworkが動作していればManagedなデバッガーが動作し、そうでなければNativeなデバッガーとなります。

    C++/CLIはManagedとNativeの両方を扱えますが、デフォルトでデバッガーはManaged部分しか扱いません。そのため、NativeコードであるOutputDebugString()は無視されているのだと思います。

    解決策としては、デバッガーのモードを混合に変更するか、ManagedなSystem::Diagnostics::Debug::WriteLine()を使います。

    2017年9月16日 7:23
  • Windows フォーム アプリケーション でプロジェクトを作成されていたんですね。

    こちらで、同じように Visual C++ の Windows フォーム アプリケーション でプロジェクトを作成したところ再現しました。

    どうも、OutputDebugString が動作しないのは、プロジェクトの設定「構成プロパティ」→「全般」→「共通言語ランタイム サポート」が「純粋 MSIL 共通言語ランタイム サポート (/clr:pure)」となっているときに、OutputDebugString が出力されないようです。

    こちらを、「共通言語ランタイム サポート (/clr)」に変えたところ、OutputDebugString での出力が正しくされました。

    追伸:

    Visual C++ Windows フォーム アプリケーションのデバッグ出力では、OutputDebugString を使うのではなく、

    System::Diagnostics::Debug::WriteLine("*** test ***");

    というようにコードを書くと出力ウィンドウに文字を出力できると思います。

    2017年9月16日 7:25
  • プロジェクト作成時に"Windowsフォームアプリケーション"として作成した場合、OutputDebugString()を実行しても、Visual C++上の"イミディエイトウィンドウ"に出力されないという症状になります。

    その話、極めて重要なんですけれども…。

    デバッグ対象のプロセスがマネージコード始まりであり、プロジェクトのデバッグプロパティの「デバッガーの種類」が「自動」、あるいは「マネージのみ」なら OutputDebugString の文字列は表示されません。
    「ネイティブのみ」、あるいは「混合」にする必要があります。
    (結果的に、デバッガを正しく使えていないという問題です)

    なお、混合デバッグの場合は、デバッガのデタッチができないという制限があります。

    2017年9月16日 7:26
    モデレータ

すべての返信

  • 私の環境(Windows 10 x64, Visual Studio 2010)では再現が出来ませんでした。

    回答ではなく質問ですが、出力できないプロジェクトとは別に新しいプロジェクトで C++ の空のコンソールアプリケーションを作成し、下記のようなコードを動かしても OutputDebugString は出力されないのでしょうか?

    #include <windows.h>
    
    int main()
    {
    	OutputDebugString(TEXT("*** test ***\r\n"));
    	return 0;
    }

    既存のプロジェクトのみで再現する現象か切り分けるためご確認できますでしょうか?
    2017年9月10日 9:01
  • 回答ありがとうございます。

    早速、以下のコードのコンソールアプリでトライしました。

    #include "stdafx.h"
    #include <windows.h>
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	OutputDebugString(TEXT("*** test ***\r\n"));
    	return 0;
    }

    正しく出力されますね。

    つまり、出力されないプロジェクトファイルの設定問題ということでしょうか?

    2017年9月15日 21:07
  • Visual Studioおよびデバッガーは正しく出力されるよう構成されています。ですので、当該プログラムがあえて表示しないよう何らかの操作が行われていると思われます。それ以外だと、そもそも当該行が実行されていない・そもそも別のバイナリを実行していた等もありますが、第三者にはわかりません。
    2017年9月15日 22:18
  • 返信ありがとうございます。

    私も一応元職業プログラマーですので、該当exeが実行され、該当コードも実行されていることは事前に確認済みです。

    知りうる限り、OutputDebugStringW()/OutputDebugStringA()含めて文字コードや、プロジェクト設定等を確認したのですが、出力されずに困り果てて、質問させて頂きました。

    2017年9月15日 23:13
  • OutputDebugString が出力されないプロジェクトで、下記のようなコードを動かしてみて、出力されますでしょうか?もし出力されるのであれば、プロジェクトのどこか(追加されている*.LIBを含む)で OutputDebugStringW が別に定義されてしまっていることも考えられます。

    typedef VOID(WINAPI *PODSW)(LPCWSTR);
    PODSW fnOutputDebugString = (PODSW)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "OutputDebugStringW");
    if (fnOutputDebugString)
    {
    	fnOutputDebugString(L"*** test ***\r\n");
    }
    2017年9月16日 0:14
  • ありがというございます。
    頂いたコードを早速実装し、fnOutputDebugStringにアドレスが取得できた上で"fnOutputDebugString(L"*** test ***\r\n");"を処理しても、出力されませんでした。
    一応、Debugビルドして、ステップ実行もして該当処理が実行されていることを確認済みです。

    ふと、コンパイル済みのexeを実行した際に、偶然DebugView.exeを立ち上げていたのですが、DebugViewには文字列が出力されていました。

    まとめると

    ・新規のコンソールアプリプロジェクトを作成した際には、Visual C++上の"イミディエイトウィンドウ"に出力される(Visaul C++の設定には問題ない?)
    ・今回のプログラムは、プロジェクト作成時にWindowsフォームアプリケーションとして作成していますが、"kernel32.dll"からアドレスを直接取得してコールしてもVisual C++上の"イミディエイトウィンドウ"に出力されない(つまり、今回作っているアプリに組み込んでいるlib等にはオーバーライドされていない?)
    ・新規のWindowsフォームアプリケーションを作成して、"int main"内でOutputDebugString()しても"イミディエイトウィンドウ"に出力されない
    ↑で作成したexeを単体で実行した場合、DebugView上には出力される

    という事で、プロジェクト作成時に"Windowsフォームアプリケーション"として作成した場合、OutputDebugString()を実行しても、Visual C++上の"イミディエイトウィンドウ"に出力されないという症状になります。
    ビルド→exe単体で実行→DebugViewで動作確認という手順をとれば、デバッグ可能な状況ですが、変数のウォッチ等も同時進行で行いたく、みなさんのお知恵をお貸しください。

    2017年9月16日 6:43
  • 「Windowsフォームアプリケーション」というキーワードが気になりました。C++/CLIをお使いでしょうか。

    Windowsには.NET Framework上で動作するManaged環境と.NET Frameworkを使用しないNative環境の2種類が存在します。デバッガーは双方をサポートしていますが通常、その両方を必要とすることは稀なため、どちらか一方のみが有効化されます。具体的には.NET Frameworkが動作していればManagedなデバッガーが動作し、そうでなければNativeなデバッガーとなります。

    C++/CLIはManagedとNativeの両方を扱えますが、デフォルトでデバッガーはManaged部分しか扱いません。そのため、NativeコードであるOutputDebugString()は無視されているのだと思います。

    解決策としては、デバッガーのモードを混合に変更するか、ManagedなSystem::Diagnostics::Debug::WriteLine()を使います。

    2017年9月16日 7:23
  • Windows フォーム アプリケーション でプロジェクトを作成されていたんですね。

    こちらで、同じように Visual C++ の Windows フォーム アプリケーション でプロジェクトを作成したところ再現しました。

    どうも、OutputDebugString が動作しないのは、プロジェクトの設定「構成プロパティ」→「全般」→「共通言語ランタイム サポート」が「純粋 MSIL 共通言語ランタイム サポート (/clr:pure)」となっているときに、OutputDebugString が出力されないようです。

    こちらを、「共通言語ランタイム サポート (/clr)」に変えたところ、OutputDebugString での出力が正しくされました。

    追伸:

    Visual C++ Windows フォーム アプリケーションのデバッグ出力では、OutputDebugString を使うのではなく、

    System::Diagnostics::Debug::WriteLine("*** test ***");

    というようにコードを書くと出力ウィンドウに文字を出力できると思います。

    2017年9月16日 7:25
  • プロジェクト作成時に"Windowsフォームアプリケーション"として作成した場合、OutputDebugString()を実行しても、Visual C++上の"イミディエイトウィンドウ"に出力されないという症状になります。

    その話、極めて重要なんですけれども…。

    デバッグ対象のプロセスがマネージコード始まりであり、プロジェクトのデバッグプロパティの「デバッガーの種類」が「自動」、あるいは「マネージのみ」なら OutputDebugString の文字列は表示されません。
    「ネイティブのみ」、あるいは「混合」にする必要があります。
    (結果的に、デバッガを正しく使えていないという問題です)

    なお、混合デバッグの場合は、デバッガのデタッチができないという制限があります。

    2017年9月16日 7:26
    モデレータ
  • 正しく環境の情報出せずお手数おかけしました。私の知識もだいぶ時代遅れになっていました(涙)

    ①昔ながらのNative環境でhttp関連のコードを実装

    ②cookie周りでIE標準コンポーネントを使う必要が発生

    ③よく理解出来ていないC++/CLI(Managed)で、①で作ったNative環境のコードを組み込む

    ④OutputDebugString()が動かず・・・

    という状況でした。

    デタッチは昔ながらほぼ使用しないスタイルなので、混在環境で使います。

    回答ありがとうございました。

    2017年9月16日 8:44
  • 回答ありがとうございました。
    環境の出し方に不足がありまして、お手数をおかけしました。
    2017年9月16日 8:44
  • 回答ありがとうございました。
    環境の出し方に不足がありまして、お手数をおかけしました。
    2017年9月16日 8:45