WinCE/WEC のウォッチドッグタイマ機能(補足).NET CF アプリケーションとカーネルランドを一緒にデバッグ(1/2)

.NET CF アプリケーションからデバッグメッセージ出力

2012/03/29 koga

C# や Visual Basic で WinCE/WEC のアプリケーションを開発する際に、デバッグメッセージを出力する方法は、いくつかあります:

  • System.Console クラスの Write(), WriteLine() を呼び出す
  • System.Diagnostics.Debug クラスの Write()/WriteIf(), WriteLine()/WriteLineIf() を呼び出す
  • P/Invoke を使って NKDbgPrintfW() を呼び出す

上に挙げた三つの方法について、それらがどう違うのか、以下に述べます。なお、ここでは、.NET CF (.NET Compact Framework) の 3.5 について記します。

■System.Console クラスを使う場合
このクラスのメソッド一覧は、次のリファレンスページに載っています:

 Console Methods
 http://msdn.microsoft.com/en-us/library/system.console_methods(v=vs.90).aspx

System.Console クラスの Write() や WriteLine() を呼び出すと、コンソールウィンドウが開いて、引数に渡した文字列が表示されます。これは、ネイティブコードの場合に、printf() などを使って標準出力へ出力した場合と同じ振る舞いです。クラス名の通り、コンソールデバイスに出力する API というわけです。

■System.Diagnostics.Debug クラスを使う場合
このクラスのメソッド一覧は、次のリファレンスページに載っています:

 Debug Methods
 http://msdn.microsoft.com/en-us/library/system.diagnostics.debug_methods(v=vs.90).aspx

System.Diagnostics.Debug クラスの Write() や WriteLine() を呼び出すと、アプリケーションをデバッガから実行している場合には、デバッガの出力ウィンドウに文字列が出力されます。デバッガから実行していない場合(通常実行の場合)には、何も起きません。この振る舞いは、OutputDebugString() を呼び出した場合と同様です。

このクラスの Write() や WriteLine() の呼び出しが、OutputDebugString() の呼び出しと同様になるのは、System.Diagnostics.DefaultTraceListener クラスの働きによるものです。DefaultTraceListener クラスの説明は、次のリファレンスページに載っています。

 DefaultTraceListener Class
 http://msdn.microsoft.com/en-us/library/system.diagnostics.defaulttracelistener(v=vs.90).aspx

System.Diagnostics.DefaultTraceListener のインスタンスは、System.Diagnostics.Debug クラスの Listeners プロパティのデフォルト要素であり、そのため、Write() や WriteLine() によるデバッグメッセージ出力は、通常は System.Diagnostics.DefaultTraceListener の Write(), WriteLine() に渡されます。そして、System.Diagnostics.DefaultTraceListener は、Write() や WriteLine() に渡された文字列を引数にして OutputDebugString() を呼び出す、というわけです。

ただし、ネイティブコードで OutputDebugString() を直接呼び出した場合とは異なり、アプリケーションをデバッガから実行していないと、System.Diagnostics.Debug の Write() や WriteLine() を呼び出しても、一切出力されません。一方、ネイティブコードから OutputDebugString() を呼び出した場合は、アプリケーションデバッガから実行していなくても、WinCE/WEC のカーネルデバッガを実行していれば、カーネルデバッガの出力ウィンドウに文字列が出力されます。.NET CF のアプリケーションから P/Invoke で直接 OutputDebugString() を呼び出した場合にどうなるかは、確認していませんが、おそらく、ネイティブコードから OutputDebugString() を呼び出した場合と同じになるのではないかと思います。興味のある方は、試してみて下さい。

System.Diagnostics.Debug クラスの使い方については、次のサポートページも参考になるでしょう:

 How to trace and debug in Visual C#
 http://support.microsoft.com/kb/815788/en-us

■NKDbgPrintfW() を P/Invoke で呼び出す場合
さて、ネイティブコードの場合、デバッグメッセージの出力は、DEBUGMSG() マクロを使うのが普通です。C# や Visual Basic では、このマクロは使えませんので、その代わりに、DEBUGMSG() マクロが使っている NKDbgPrintfW() を、P/Invoke で直接呼び出す必要があります。

たとえば、次のページにあるフォーラムの質問でも、そのような回答がなされています:

 DebugMsg macro in C#
 http://us.generation-nt.com/answer/debugmsg-macro-c-help-51715972.html

.NET CF アプリケーションから、P/Invoke で NKDbgPrintfW() を直接呼び出した場合は、アプリケーションをデバッガから実行していない場合でも、WinCE/WEC のカーネルデバッガを実行していれば、カーネルデバッガの出力ウィンドウに文字列が出力されます。.NET CF アプリケーションを、ネイティブコードのアプリケーションやライブラリと一緒にデバッグしていて、追跡したい個所の呼び出しタイミングの関係を知りたい場合には、NKDbgPrintfW() を使うと、デバッグメッセージをカーネルデバッガの出力に渡すことができます。つまり、.NET CF アプリケーションのデバッグメッセージも、ネイティブコードのデバッグメッセージも(さらには、デバイスドライバのデバッグメッセージも)同じ出力に出せますので、それらを同時に追跡したい場合には、便利でしょう。

なお、P/Invoke で NKDbgPrintfW() を直接呼び出すと、ネイティブコードで DEBUGMSG() マクロを使った場合とは異なり、リリースビルドでもデバッグメッセージが出力されてしまいます。その点は、注意して下さい。デバッグビルドの時にだけデバッグメッセージが出力されるようにするには、System.Diagnostics.ConditionalAttribute を使ってデバッグビルドに対してのみ有効にするか、または、#if … #endif を使って条件コンパイル指定して下さい。ちなみに、System.Diagnostics.Debug クラスの Write() や WriteLine() では、System.Diagnostics.ConditionalAttribute を使っています。

Entry Filed under: .NET Compact Framework, アプリケーション開発

Leave a Comment

Required

Required, hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed


Categories

Links

Posts by Authors

Recent Posts

Calendar

2012年3月
« 2月   4月 »
 123
45678910
11121314151617
18192021222324
25262728293031

Posts by Month

Posts by Category

Meta