非VisualStudio環境でC++/CLIが動かない問題の解決策

まータイトル通りなんですが、同様の現象で困っている方も多いと思いますので、ここにまとめておきます。

はじめに

自分はよく、研究開発プロジェクトやデモアプリの制作のために、GUI部をC#で作って画像処理部をC++で作る、といったことをします*1C#コードからC++コードを呼び出す方法としては DllImportC++/CLIを用いた薄いラッパー経由 の二つがあり、個人的には後者をよく用います。(後者について【id:wosugi:20100211】が参考になるかも。)

問題

ただ、このC++/CLI、VisualStudioがインストールされてない環境ではエラーが発生する、という問題がありました。具体的には、C++/CLIで作ったDLLにアクセスした際に「System.IO.FileLoadException」というのが発生します。要するに「あるべきDLLが見つかりませんよ〜」と言ってるわけですが、『VisualC++ 再頒布可能パッケージ』はインストールしてるし、必要なDLLはすべて入れているはず、、、一体何が足りないのか??。なかなか具体的にイメージしづらく見当しづらいエラーです。一体コレはどういう事なのか。。。

調査

これは『Dependency Walker』というソフトを使うと手がかりがつかめます。(C++/CLIで作った)エラーの生じるDLLを Dependency Walker で解析すると、いくつかのあるべきDLLが見つからないというメッセージが出ます。自分の場合、次の3つが出てきました。

  • msvcr90d.dll
  • ieshims.dll
  • wer.dll

結論から言うと「msvcr90d.dll」がない、というのがエラーの肝でした(他の二つはなくてもOKらしい)。これはVisualC++で作られたプログラムが必要するDLL?のようで、“90”というのは(たぶん)VS2008を表し、“D”はデバッグモード用を意味します。
んで実は、再頒布可能パッケージにはリリースモード用(例えば、msvcr90.dll)のみが含まれており、デバッグモード用は含まれてません。VisualStudio2008をインストール済の場合には以下の場所にデバッグモード用が入ってます。

解決策

上記フォルダの中にある4つのファイル全てを、C++/CLIで作ったDLLの場所におけばとりあえず動くようになりました。ただし、このD付きのファイル群は再頒布が不可能なようです。したがって、一般公開とかは法律上できないと思われます。一般公開する場合はリリースモードにしましょう、ということですね。

おわりに

実は半年前くらいにも同じ問題に直面し、当時はエラーの詳しい出所が全くつかめず(例外名すら分からず・・・)、結局DllImportに逃げて回避しました。先週再びこの問題に直面し、今回は例外名が分かったこともあって、無事に解決できました。なんか、こういう基本的なインフラに関する部分くらい、ちゃんとサポートして欲しいなぁとマイクロソフトにはかなり文句があります。とりあえず、お困りの方、ご参考に。

参考URL

*1:C++は御世辞にも美しい言語とは言えませんが、細かい点まで融通が効く言語というのはナカナカなくて、消去法的にC++を使ってます。