特集

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

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

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

●(1)できるだけ.NET Frameworkを利用する

 こちらの方針に従うなら、元のコードにあるCStringクラス(MFC)をStringクラス(.NET)に書き換え、Documentが内包する(スタックを表現している)コンテナを、例えばListジェネリック・クラス(System::Collections::Generic名前空間)に置き換えることになります。

 以下は実際に書き換えたDocumentのヘッダ・ファイルとソース・ファイルのコードです。

// StringStackDocument.h
namespace dotNet {
  public ref class StringStackDocument : StringStackInterface {
  public:
    StringStackDocument();
    virtual void Push(System::String^ element);
    ……省略……
  private:
    System::Collections::Generic::IList<System::String^>^ container_;
    event System::EventHandler^ handler_;
  };
}
MFCの各クラスを.NETのクラスに置き換えたDocumentのヘッダ・コード(StringStackDocument.h)
 
// StringStackDocument.cpp
#include "stdafx.h"
#include "StringStackDocument.h"

namespace dotNet {

  StringStackDocument::StringStackDocument() {
    container_ = gcnew System::Collections::Generic::List<System::String^>();
  }

  void StringStackDocument::Push(System::String^ element) {
    container_->Add(element);
    handler_(this, nullptr);
  }

  ……省略……
  void StringStackDocument::AddObserver(System::EventHandler^ handler) {
    handler_ += handler;
  }

  void StringStackDocument::RemoveObserver(System::EventHandler^ handler) {
    handler_ -= handler;
  }
}
MFCの各クラスを.NETのクラスに置き換えたDocumentのソース・コード(StringStackDocument.cpp)
AddObserverメソッドはViewのOnUpdateメソッドをUpdateAllViewsイベント・ハンドラとして登録するためのもので、RemoveObserverメソッドは登録を解除するためのもの。

 この方針を貫くならば何もわざわざDocumentをC++/CLIで実装する必要はありませんね。全部C#なりVBなりで書けばいい。ただ、Documentが既存の C/C++ネイティブなライブラリを必要としているならC++/CLIで実装しておくとライブラリの使用が楽になります。

 このサンプル・プログラムはここ(dotNetStringStack1.zip)からダウンロードできます。

●(2)できるだけネイティブなC++コードを残す

 こちらの場合.NET Frameworkが提供するクラスを避けることになります。なので、例えば元のコードにある(MFCの)CStringクラスを(標準C++ライブラリの)std::wstringクラスに、Documentが内包するコンテナをstd::vectorクラスに置き換えることになります。

// StringStackDocument.h
#include <vector>
#include <string>

namespace
dotNet {
  public ref class StringStackDocument : StringStackInterface {
  public:
    StringStackDocument();
   ~StringStackDocument();
   !StringStackDocument();
    virtual void Push(System::String^ element);
    ……省略……
  private:
    std::vector<std::wstring>* container_;
    event System::EventHandler^ handler_;
  };
}
MFCの各クラスを標準C++ライブラリのクラスに置き換えたDocumentのヘッダ・コード(StringStackDocument.h)

 ただし前編で述べたとおり、ネイティブ・オブジェクトをマネージ・クラスのメンバに置くことができず、ポインタを介することになるのがやや(かなり?)面倒です。

 さらに必要に応じてネイティブ⇔マネージ変換が必要となりますが、これは“できるだけ.NET Frameworkを利用する”方針であってもネイティブC/C++ライブラリを使うなら同様の手間が発生します。

// StringStackDocument.cpp
#include "stdafx.h"
#include "StringStackDocument.h"

namespace dotNet {

  // System::String→std::wstring
  static std::wstring FromCLI(System::String^ input) {
    std::wstring result;
    if ( input != nullptr && input->Length > 0 ) {
      pin_ptr<wchar_t> pin = &input->ToCharArray()[0];
      result.assign(pin, input->Length);
    }
    return result;
  }

  // std::wstring→System::String
  static System::String^ ToCLI(const std::wstring& input) {
    return gcnew System::String(input.data(), 0, input.size());
  }

  void StringStackDocument::Push(System::String^ element) {
    container_->push_back(FromCLI(element));
    handler_(this, nullptr);
  }

  System::String^ StringStackDocument::Pop() {
    System::String^ result = ToCLI(container_->back());
    container_->pop_back();
    handler_(this, nullptr);
    return result;
  }
  ……省略……
}
MFCの各クラスを標準C++ライブラリのクラスに置き換えたDocumentのソース・コード(StringStackDocument.cpp)
FromCLIメソッドはマネージ・コード文字列からネイティブ・コード文字列に変換するためのもので、ToCLIメソッドはその逆の変換を行うためのもの。

 このサンプル・プログラムはここ(dotNetStringStack2.zip)からダウンロードできます。

 どちらを選択するかはプログラマーの好みではありますが、後者を選べば.NETでないプラットフォームへの移植が楽になります。

 次回は、次期Visual Studio(コードネーム“Orcas”)で搭載予定のSTL/CLRを紹介します。STL/CLRでは、vectorクラスやmapクラスなどのコンテナにマネージ・オブジェクトを格納でき、ポインタを介さずに直接マネージ・クラスのメンバとすることができます。その結果、普段標準C++での実装に慣れたプログラマーにとって、C++/CLIでのプログラミングが非常に楽になります。End of Article


 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 記事ランキング

本日 月間