開発環境 | Visual C++ 2008(Standard Edition以上) |
本日はVisual Studio 2008のマルチスレッドデバッグ機能を紹介します。
従来のVisual Studioからあった機能ですが、ほんのちょっとだけ進化しているようです。
まずは従来からある機能を紹介します。
Visual Studio 2008でマルチスレッドアプリケーションをデバッグ実行すると、
以下のようなスレッドウィンドウを見ることができます。
大体見た目通りの機能です。
それぞれのスレッドのIDや名前、実行中の場所を表示してくれます。
この場合は、メインスレッドがDibInfo::CreateDib
を実行中で、ワーカースレッドがDibBox::Load
を実行中であることが分かります
(DibInfoがなんであるかとかそういうのは気にしないで下さい)。
スレッドウィンドウのワーカースレッドをクリックすると、以下のようになります。
ワーカースレッドの実行中の場所のソースコードが表示され、呼び出し履歴もワーカースレッドのものになります。
スレッドウィンドウを右クリックすると、以下のようなメニューが表示されます。
スレッドの凍結(=SUSPEND)やフラグ設定ができます。
フラグ設定はVisual Studio 2008の新機能です。フラグを設定すると、設定されていないスレッドと簡単に区別できるようになります。
スレッドがたくさんあり、注目したいスレッドを絞り込みたいときに便利そうです。上記の例のようにスレッドが2つのときはなんの役にも立ちませんが。
「16進数で表示」を選ぶとスレッドIDが16進数で表示されます。これもたぶんVisual Studio 2008の新機能です。
新機能というにはしょぼいですが、スレッドIDを16進数でデバッグ出力するようなコードと相性が良いです。
Visual Studio 2008のマルチスレッドデバッグ機能はこれで全てのようです。
特定のスレッドだけのステップ実行機能は欲しいと思ったのですが、無いようです(なんでやねん)。
他のスレッドを全て凍結させてからステップ実行すれば実現できますが、面倒です。
以上で紹介はお終いです。
今までより進化したのかどうか微妙なところです。
まだ使い込んでいないので安定性は分かりません。
Visual Studio 6.0やVisual Studio.NET 2003では、マルチスレッドアプリデバッグ中に開発環境が落ちる(反応しなくなる)ことが
良くありました。改善されているのを期待したいところです。
開発環境 | Visual C++ 2008 |
Visual Studio 2008を買ってからほぼ毎日ちょっとずつ触っていますが、GUIが今まで使っていたVisual Studio.NET 2003とあんまり変わらないので慣れるのは早そうです。
まだboostが公式に2008に対応していないあたりがちょっと辛いですが。
C++では、昔は半角文字は1バイト、全角文字は2バイトと可変長になっており、文字列処理が大変面倒でした。
JavaやC#では、半角文字も全角文字も1文字2バイト固定になっていて、大変羨ましく感じたものでした。
そこで、C++でも文字を扱うときはwchar_t
を使い、1文字を固定長にしようとしてみたことがあります。
文字列はstd::wstring
を使えば問題なかったのですが、標準ライブラリを使ったファイルI/Oに問題がありました。
Visual Studio.NET 2003のstd::fstream
のopen
メンバは、
open(const char *_Filename, (略)
しかありませんでした。wchar_t
ベースのファイル名をstd::fstream
に渡すことができなかったのです。
そこで仕方がなく、WideCharToMultiByte
を使ってchar
ベースの文字列に変換したり、別のライブラリを使ったりしていますた。
これが、Visual Studio 2008では解決されています(Visual Studio 2005の時点で既に解決されていたみたいです)。
std::fstream
に
open(const wchar_t *_Filename, (略)
というメンバが追加されました。これでファイル名をwchar_tベースで管理できます。ありがたいことです。
ようやくUnicodeアプリケーションのファイルI/Oに標準ライブラリを使えるようになりました。
開発環境 | Visual C++ 2008 |
ライブラリ | boost 1.34.1 |
Visual Studio 2008のインテリセンスは、Visual Studio.NET 2003に比べて良くなっています。(Visual Studio 2005は持ってないので比較できません)
特にboostを使ったコードが書きやすくなっています。例を数点紹介します。
boost::shared_ptr
越しでもちゃんとメンバ一覧が表示されます。
boost::shared_ptr
自身のメンバもばっちり
boost::tuple
も問題ありません。
メンバ関数テンプレートなので、<>
を入れろということまで教えてくれます。
boost::tuple
とboost::shared_ptr
が組み合わさっていても問題なし。
こんなおまけ機能もあります。候補ウィンドウ表示中に、Ctrlを押すとウィンドウが半透明になります。というよりほとんど見えなくなります。
これはVisual Studio 2008の新機能らしいです。
コードが混み合っている時は便利かもしれません。
なお、Visual Studio.NET 2003では、上記のインテリセンスは全てこのメッセージで拒否されました。
ソフトウェア工房αさんがリリースしているlibjpeg高速化改造版をVisual Studio 2008で使う方法を調べましたので、まとめておきます。
(正式名称はIndependent JPEG Group's JPEG software release 6b with x86 SIMD extension for IJG JPEG library version 1.02)
(Visual C++.NET 2003の場合はこちら)
必要なもの
手順
libjpeg高速化改造版の機能は、jpeglib.hを#includeすると使えるようになります。
IJGが配布しているIJG JPEG library(libjpeg、jpeglib、jpeg-6bと呼ばれることもあるようです)をVisual Studio 2008で使う方法を調べましたので、まとめておきます。
(Visual C++.NET 2003の場合はこちら)
必要なもの
手順
Visual C++.NET 2003はC++ランタイムが6種類あったのですが、2008ではシングルスレッド用のランタイムがなくなり、4種類になったようです。
libjpegの機能は、jpeglib.hを#includeすると使えるようになります。
このとき、標準的なヘッダ(windows.hなど)と干渉を起こすことがありますが、以下のように書くと回避できます。
#define XMD_H #undef FAR extern "C" { #include <jpeglib.h> }
以上です。
「Visual Studio 2008 Professional Edition アップグレード」なるものを買ってみました。
私の場合はVisual Studio.NET 2003からのアップグレードになります。
私が使うのはC++です。Visual Studio.NET 2003のC++開発環境は標準への準拠度が高く、boostライブラリもちゃんと使えて良い開発環境でした。 C++しか使わないのであれば、当面Visual Studio.NET 2003で十分だと思っていたのですが、 VistaでVisual Studio.NET 2003がサポートされない という悲しい出来事があり、やむなくアップグレードすることにしました。
インストールメディアですが、DVD1枚にまとまっていました。
インストールは相変わらず数時間かかりますが、昔のようにCD入れ替えの手間が無く、楽でした。
インストール後にService Releaseのチェックをしようとすると、
IEでしか見れないページをデフォルトブラウザ(私の場合はFirefox)で開くのはちょっと困りました。
IEでしか見れないページならばちゃんとIEを使って欲しいところです。
価格は、アップグレード版は61,236円、アップグレードじゃない方は120,960円。6万円も違いがあります。
アップグレード版の適用範囲は異常に広く、
6万円以内の商品もたくさんあります。
Officeの方もこんな感じでした。
Microsoftのアップグレード版の価格戦略は良く分かりません。
ちなみに私はVisual C++ 9.0 Express EditionしかインストールしていないノートPCにアップグレード版をインストールしてみたのですが、
CDを要求されることもなくすんなりインストールできてしまいました。うーむ一体これは・・・?
以前書いたコードのバージョンアップ版です。
仕様は以前と同じです。若干コードがスマートになっている・・・かもしれません。
std::string UnicodeToMultiByte(const std::wstring& Source, UINT CodePage = CP_ACP, DWORD Flags = 0); std::string UnicodeToMultiByte(const std::wstring& Source, UINT CodePage, DWORD Flags) { std::vector<char> Dest(::WideCharToMultiByte(CodePage, Flags, Source.c_str(), static_cast<int>(Source.size()), NULL, 0, NULL, NULL)); return std::string(Dest.begin(), Dest.begin() + ::WideCharToMultiByte(CodePage, Flags, Source.c_str(), static_cast<int>(Source.size()), &Dest[0], static_cast<int>(Dest.size()), NULL, NULL)); }
std::wstring MultiByteToUnicode(const std::string& Source, UINT CodePage = CP_ACP, DWORD Flags = 0); std::wstring MultiByteToUnicode(const std::string& Source, UINT CodePage, DWORD Flags) { std::vector<wchar_t> Dest(::MultiByteToWideChar(CodePage, Flags, Source.c_str(), static_cast<int>(Source.size()), NULL, 0)); return std::wstring(Dest.begin(), Dest.begin() + ::MultiByteToWideChar(CodePage, 0, Source.c_str(), static_cast<int>(Source.size()), &Dest[0], static_cast<int>(Dest.size()))); }
ところで、C++標準ライブラリを使ってプログラムするとき、wchar_tをメインに使おうとすると、ファイルが開けなくてこまります。
なんでstd::fstreamはファイル名にconst char *しか指定できないんでしょうね。
おかげでこんな変換関数を使うハメに陥ってしまいます。