C++/CLIにインテリセンスが必須な理由

Visual Studio 2010 の C++/CLI ではインテリセンスが効かないのです。

C++では、効くし、最新情報にある通り結構早くなっています(最初にヘッダファイル等を読み込んでデータベース化するところは相変わらずなんですが)。

さて、これを /clr スイッチを付けて、C++/CLI として使おうとすると、全く駄目。C++ 側のインテリセンスも、.NET側のインテリセンスも両方が効きません。全く、昔の vi で組んでいた状態に戻ります。

このインテリセンスの機能、C++/CLIで使えないのは、.NET Framwork を選択するという点でも結構致命的なのです。

それをいくつか説明しましょう。

 

■C++で組むときにインテリセンスがでない

MFCで組む時には出てたインテリセンスが、C++/CLIでは出ない訳ですから、かなり不便です。ただし、不便とはいえ、C++ のヘッダファイルを参照すれば、(かなり面倒ですが)クラス名から関数名を割り出すことができます。

ただし、Visual C++ 6.0 の頃から出ていたもの(10年前)以前に逆戻りというのは、かなり開発効率が落ちるでしょう。

なので、C++/CLI のコンパイラを捨てて、C++ だけでコンパイルするでしょうね。

そうなると、MFC でのインテリセンスも使えるのでうまくできます。

 

■.NETとしてC++/CLIを使う場合に困る

C#やVisual Basicで出ていたインテリセンスが出ないので、結構困ります、、、が、ヘルプを参照すれば何とかコーディングができるでしょう。

しかし、.NET FrameworkでWindowsアプリを組む場合、C++/CLIだけで組むことは皆無でしょう。C#やVisual Basicを選択しますよね。

C++/CLIで作る場合は、学習用か趣味のときぐらいです。

また、C++/CLIで使い勝手が悪かったら、C#やVisual Basicを使えばいいだけです。

 

■ハブとしてC++/CLIを使う場合に、致命的

さて、これが一番の問題です。

C++/CLIの使いどころは、実は既存のC/C++ライブラリと.NETアプリケーションを媒介するところなのです。例えば、OpenCV という画像解析用のライブラリがありますが、これはC++で書かれています。このために、ライブラリを利用するためには、C++の呼び出し(あるいは専用に用意されたC言語呼び出し)が必要になります。

ご存じのとおり、C#やVisual Basicではポインタが扱えません。正確に言えば、C#でboxingを使えば、ポインタを使えるのですが非推奨の機能です。また、適切な呼び出しの属性を付ければ、C#からC言語で作られたDLLを呼び出すことができますが、結構手間です。

さて、この場合は、C言語のライブラリに適当なC++/CLIのラッパを作ります。

つまり、

C言語 → C++/CLI → C#

のような流れを作ってやるわけです。

こうすると、C言語特有のポインタや配列、char型での文字列(ASCIIのみなど)は、C++/CLIでうまく扱ってやり、配列の場合はArrayやList、文字列の場合はstringクラスに直してから C# へ引き渡してやります。

これらの利点は、

  • C言語のライブラリで扱う malloc 関数などを C++/CLI で吸収できる。
  • C#のstringクラス(Unicode)に直すことで、char型の配列を直接変換する必要がない。

また、C言語のライブラリが、昔からある計算ライブラリのような場合(社外秘となる画像解析や暗号解析のライブラリなど)を適度にクラスとしてくるんでやり、C#やVisual Basic のオブジェクト指向で扱いやすいパターンにします。そうすることで、主に.NET側でUIを記述し、高速化しなければならない科学計算などはC++を使ってポインタを駆使することが可能です。

さて、ここでC++/CLIを使う場合、C言語の科学計算ライブラリは、ヘッダファイルがあるために、インテリセンスがなくてもそれなりに記述ができます。非常に面倒ではありますが、なんとか記述可能です。

しかし、C#側で作成したUIライブラリなどを、C++/CLIに引き渡す場合に、非常に困るのです。C#の場合には、ヘッダファイルがないので、直接ソースコードを参照しなければ、クラスのメソッド名やパラメータが分かりません。

この場合、C#やVisual Basicで作られたコードが、DLLとして(アセンブリとして)提供される場合はどうでしょうか?

そう、C++/CLIからは全く手が出せない状態になってしまうのです。

Visual C++ 2008 の場合は、C# で作成したDLLを参照設定させた上で、.NETの各種クラスライブラリを使うことができたので、DLL内のクラスをインテリセンスを使い探索することが可能なのですが、Visual C++ 2010 の場合は、インテリセンスが効かないために、これが出きないという事態に陥ります。

そう、回避策として考えられるのは、

  • 一度、C#で組んだものを、C++/CLI にコンバートする。
  • Visual C++ 2008 で組んだものを、Visual C++ 2010 にコンバートする

という本末転倒なことになるわけですね。

これが致命的なところです。

 

ゆえに、C++/CLI のインテリセンスが出ない場合には、そのままレガシーシステムのラッパーを作れない、に等しい現象が起こるので、

  • C言語で作ったレガシーシステムを、C#に書き直すしかない。
  • C言語で作ったレガシーシステムは、C言語のみで管理するしかない。

の2点に分岐します。ただし、先に書いたとおり機密性の高いC言語ライブラリは、書き直すことは不可能ですし、高速化が必要な科学計算の場合はコアなところはC言語のままとしたいところです。

そんな場合は、C言語あるいはC++のみを使い続けるようになり、ここの分野ではC#やVisual Basicの移行は進まないでしょう。

と、なにやらぐだぐだと書きましたが、

  • 早々に、サービスリリースとかで、C++/CLIのインテリセンスを戻してくれよ!
  • それまでは、Visual C++ 2008 で C++/CLI を使うしかないね。

というのが結論ですねぇ。いまのところは。

カテゴリー: 開発 パーマリンク