特集

Vista時代のVisual C++の流儀(中編)

MFCから.NETへの実践的移行計画

επιστημη(えぴすてーめー)
2007/03/06

 前編では、ネイティブ・コードとして記述したC/C++ライブラリをマネージ・コードであるC++/CLIでラップし(すなわち.NET化)、それをC#やVisual Basic(以下VB)などの.NET言語から呼び出す手順について解説しました。

 この後を受けて、中編ではその応用としてVisual C++(以下VC++)による.NETアプリケーション構築の1つの戦術を紹介します。

C++/CLIによるWindowsフォーム・アプリケーション

 .NET FrameworkとVisual Studio-IDEの助けを借りて、VC++だけで.NETのWindowsフォーム・アプリケーションを組み上げることはもちろん可能です。ですが筆者はVC++のみでのWindowsフォーム・アプリケーション構築には少なからず疑問を感じています。

 それについて議論するために、まずはVisual Studio 2005(以下VS 2005)に(C++/CLIによる)Windowsアプリケーションのひな型を吐かせてみましょう。

●C++/CLIによるWindowsフォーム・アプリケーションのひな型コード

 次の画面のように、[新しいプロジェクトの追加]ダイアログで「Visual C++」−「CLR」の「Windows フォーム アプリケーション」テンプレートを選択して「CLIFormApp」という名前で新しいプロジェクトを作成します。

VS 2005でのWindowsフォーム・アプリケーション・プロジェクトの新規作成
Windowsフォーム・アプリケーションのひな型となるプロジェクトを作成しているところ。この[新しいプロジェクトの追加]ダイアログを表示するには、IDEのメニュー・バーから[ファイル]−[追加]−[新しいプロジェクト]を選択すればよい。

 VS 2005はWindowsフォーム(以下フォーム)に対応したマネージ・クラスのForm1クラスを、ヘッダ・ファイルのForm1.h内に生成します。C/C++言語では、ヘッダ・ファイル(Form1.h)には宣言だけを記述し、実装はソース・ファイルのForm1.cppに記述するのが一般的ですが、VS 2005のIDEは(C++/CLIによる)実装をすべてヘッダ内に押し込みます。

 さらにこの状態でWindowsフォーム・デザイナ(以下フォーム・デザイナ)でフォーム上にボタンを1つ配置し、ボタンのClickイベントに反応するハンドラを追加すると、以下のスケルトン・コードがヘッダ・ファイルに書き加えられます。

#pragma once

namespace CLIFormApp {
  ……省略……
  public ref class Form1 : public System::Windows::Forms::Form
  {
  ……省略……
  private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
    }
  };
}
Clickイベント・ハンドラが追加されたヘッダ・ファイル(Form1.h)

 要するにフォーム・デザイナで行ったすべての操作がヘッダ内に反映され、加えてプログラマーが実装すべきコードもヘッダ内にすべて書き込むことをVS 2005のIDEは要求しているわけです。

●生成されたひな型コードの是非

 ……この流儀、どう思われますか?

 長いことC/C++でコードを書いてきた筆者には居心地が悪くてたまりません。C/C++では、ヘッダ・ファイルの役割は関数のプロトタイプ宣言やクラスの宣言をコンパイラに対して提示することであり、インライン展開やテンプレートなど特別な目的がない限り実装を書くべきものではないからです。ビギナーに対しては、このようなコードは厳に戒めています。ところがVS 2005のIDEはその「やってはならない」とされるヘッダ内実装を涼しい顔してやってしまうのです。

 フォーム(Form1クラス)の実装に追加/変更を加えることは、ヘッダ・ファイル(Form1.h)に手を加えることと同義になります。ということは、たとえフォームの変更がそのクラス宣言に何の変化をもたらすものでなかったとしても、フォームを利用するコード(すなわち、「#include "Form1.h"」を記述したすべてのコード)は必要のない再コンパイルを強いられます。これは、関数やクラスの宣言をコンパイラに提示するのが目的であるヘッダに実装を詰め込むことによる弊害です。

 筆者はVS 2005が吐いたこのC++/CLIによるフォームのひな型コードの、あまりのお行儀の悪さに、正直がっかりしました。C/C++の流儀からあまりにかけ離れたコード生成であり、保守性が極めて悪いのです。

 対してC#/VBでフォームのデザインを行った場合、フォーム・デザイナが生成するコードとプログラマーが書き加えなくてはならないコードとが「部分クラス(partial class)」によってきれいに分離され、非常に見通しのよいソース・コード構成となります。

 前編で紹介したVC++開発チームの見解はこうでした。

「C#/VBと同等の.NET対応をVC++に求めるより、VC++にはC#/VBにはできないことをやらせる方向に注力したい。すなわち高速/高機能なネイティブ・コードを書くこと、そして.NETのマネージ・コードと(従来からの資産を含めた)ネイティブ・コードとの橋渡しである」

 これを踏まえて、筆者はユーザー・インターフェイス(以下UI)に絡むコードをC++/CLIで書くのは得策ではないと判断しました。

 前編からの繰り返しになりますが、CLI(Common Language Infrastructure:共通言語基盤)によって異なる言語間を自由に行き来できるのが.NETのメリットの1つであり、まさにそのためのC++/CLIなのですから、苦手(?)なUIはC#やVBに任せるのが上策ではないでしょうか。

言語をまたいだDocument/Viewアーキテクチャ

 従来のMFC(Microsoft Foundation Class)で構築されたアプリケーションの多くは、「Document/Viewアーキテクチャ」に従っています。Documentはアプリケーションの“実体”となるロジックを、Viewはその実体とエンド・ユーザーとをつなぐ“表現”となるUIを受け持ちます。エンド・ユーザーはViewを介してDocumentに対して処理を要求し、その処理結果をViewを介して手に入れます。このような構造によってアプリケーションの“実体”と“表現”を分離し、それぞれの変更/拡張が他方へ及ぼす影響をできるだけ抑えています。

 本稿では、前節での判断から“実体”をC++/CLIで、“表現”をC#で実装します。そのためにMFCのDocument/Viewアーキテクチャを踏襲しますが、本来このアーキテクチャは変更/拡張に対して堅牢なコード構成をもたらします。アプリケーションのすべてをC#あるいはVBで実装する場合でも、このDocument/Viewアーキテクチャを組み上げることを推奨します。

 MFCから.NETへの移行を考えると、DocumentをC/C++の資産を活用すべくC++/CLIで実装し、UIすなわちViewを(Win32 APIをベースとした)MFCから.NET(Windowsフォーム)に差し替え、その両者を何らかの方法でつなぐことになります。

 その前に、MFCのDocument/Viewアーキテクチャをおさらいしておきましょう。


 INDEX
  [特集]
  Vista時代のVisual C++の流儀(前編)
  Vista到来。既存C/C++資産の.NET化を始めよう!
    1.Vista時代にC/C++はもはやお払い箱なのか?
    2.C/C++資産をどこまで生かせる?
    3.ネイティブ・オブジェクトをマネージ・コードでくるむ
    4.文字コード変換
 
  Vista時代のVisual C++の流儀(中編)
  MFCから.NETへの実践的移行計画
  1.C++/CLIによるWindowsフォーム・アプリケーション
    2.言語をまたいだDocument/Viewアーキテクチャ
    3..NET移行前のMFCサンプル・アプリケーション
    4.MFCのDocument/Viewアーキテクチャの.NET化
    5.MFCで書かれたDocumentを.NET化する2つの方法
 
  Vista時代のVisual C++の流儀(後編)
  STL/CLRによるDocument/Viewアーキテクチャ
    1.STL/CLRとは
    2.STL/CLRの特徴
    3.Visual Studio 2005で試す
    4.おまけ:NUnitの活用


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間