読者です 読者をやめる 読者になる 読者になる

私がC++/CLIを嫌う理由

以前ちょろっと触れたC++/CLIは避けて通りたいという話ですが、そう思うようになった経験談を書いてみます。

はじめてだらけの.NET開発がはじまる

  • 描画ルーチンとゲームリソースコンバータはUnmanaged C++からDirectXを使って実装し、
    C#から操作するためのラッパをC++/CLIで実装
  • C++への直接操作はこのC++/CLIプロジェクトからしか行えないのでだんだんこのプロジェクトが肥大化
  • C++/CLIプロジェクトが肥大化するに伴って、このプロジェクトを使用する(参照する)プロジェクトが増加
  • あるときソリューション内のプロジェクト総数が200を超える
  • デバッグ情報肥大化の影響(たぶん)でステップ実行が激重になる。アンマネージデバッグを有効にするとより一層ひどいことに。

やばい

  • このままでは仕事にならないということでソリューションを複数に分割し、作業ソリューションを分割する方向で実験開始。
  • プロジェクト参照をdllファイル参照に変更してソリューションを分割する方法も考えたが、C#プロジェクトがdllファイル参照ではビルドフォルダ(bin/$(Configuration))へdllをコピーしてくれない。
    このときアプリはこのソリューションだけではなく、同じプロジェクト群を参照するアプリがdllをコピーされる前提ですでにビルド環境が構築されてしまっていた。
    これをすべて変更するのは面倒だ…うぬぬ…。
  • C#プロジェクト自体をソリューションからはずしてビルドしてみた。なんとビルドが通る!
    どうやらC#プロジェクトは.csprojの内容から参照を解決してくれるらしい。これは良いとばかりに200あったプロジェクトを20〜30プロジェクト単位のソリューションに分離。ほとんどのソリューションはうまいことビルドが通った。

…が、しかし!

実はC++/CLIプロジェクトはこの方法が使えない。
しかも、

  • A)C++/CLIプロジェクトを参照している場合はそのプロジェクトをソリューションに含めなくてはいけない
  • B)C++/CLIプロジェクトをビルドするにはManaged/Unmanage問わすにソリューションに含めなくてはいけない

と芋づる式に分割できないグループが…
その後さらに実験した結果、A)が実はビルドしなければ良いということに気づく。
構成マネージャでビルドチェックをはずしてC++/CLIプロジェクトをソリューションに追加、そこから依存してるものはソリューションには含めない。これでC++ライブラリもすべてのソリューションに含めなくてはいけない状況も免れた。
だけどビルドしないプロジェクトがソリューションに入ってるのはカッコ悪い。
そこで行き着いたのがC++/CLIプロジェクトをC#で一回ラップする方法。
これだとC#プロジェクトなのでソリューションに含める必要は無くなりますし、プロジェクト参照なのでdllも集められます。
最終的には作業グループのソリューションだけでデバッグできるようになった。グループ外のソースはソリューションエクスプローラには表示されないけど、.pdbがあればステップはできるので問題無し。しかしコンパイルはできないのでコンパイル用のソリューションを複数立ち上げて作業するハメになる。

ほっとひと息

で、いまがこの状態。
C++/CLIプロジェクトへの依存を限定的にすればよかったんですが、やっぱしいろんなプラグインがいろんな描画や描画リソース管理を呼んじゃうわけで。コンバータもC++で書いてたから全部ここ経由なんですよね。
ちなみに後でよくよく考えてみたらソリューションからC#プロジェクトをアンロードしたり、C++/CLIプロジェクトのビルドチェックをはずしたりすれば同じことなんですけどね。あ、でも各人がそれをやるのは馬鹿らしいかな。

結論

  • C++/CLIのプロジェクトをわざわざC#でラップするくらいなら、
    C++/CLIを使わずにC++のDLL作ってC#にDllImportすればよかった。という話。
  • というわけでVisualStudio2008と2010に期待。
  • あー、それにしても長くてまとまりの無い日記だ。