特集

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

Vista到来。既存C/C++資産の.NET化を始めよう!

επιστημη(えぴすてーめー)
2007/01/31
Page1 Page2 Page3 Page4

●Win32スタティック・ライブラリ(C++クラス)の準備

 先ほどのhello関数と同様、簡単なネイティブ・クラスを考えます。ここでは「counter」という名前のソリューションとプロジェクトを作成し、counterクラスをC++で実装します(以下の開発手順は先ほどとほぼ同じなので詳細は省略します)。

#ifndef COUNTER_H__
#define COUNTER_H__

class counter {
private:
  int value_;
public:
  counter();
  void increment();
  int value() const;
};

#endif
Win32スタティック・ライブラリのC++ヘッダ・ファイル(counter.h)
このコードでは、先ほどのC言語による関数と違って、C++のクラスを利用している。
 
#include "counter.h"

counter::counter() : value_(0) {
}

void counter::increment() {
  ++value_;
}

int counter::value() const {
  return value_;
}
Win32スタティック・ライブラリのC++ソース・ファイル(counter.cpp)
counterクラスのincrementメソッドはカウントを1つ上げるという動作を行う。valueメソッドはそのカウント値を戻り値として返す。

 プロジェクトをビルドし、Win32スタティック・ライブラリとしてcounter.libファイルを生成します。

●.NETダイナミック・ライブラリ(薄いラッパー)の作成

 このWin32スタティック・ライブラリをC++/CLIのマネージ・コードのクラスでラップしなければなりません。「counterlib」という名前のCLRクラス・ライブラリのプロジェクトを作成し、以下のようなクラスで先ほどのcounterクラスをラップします。

#include "counter.h"

public ref class CounterLib {
  counter counter_; // ネイティブ・コードのクラス
public:
  CounterLib();
 ~CounterLib();
 !CounterLib();
  void Increment();
  property int Value { int get(); }
};
エラーが報告される.NETダイナミック・ライブラリのC++/CLIヘッダ・ファイル(counterlib.h)

 しかし、これをビルドすると次のようなエラーが報告されます。

error C4368: 'counter_' をマネージ 'CounterLib' のメンバとして
             定義できません。混合型はサポートされていません
VS 2005のエラー一覧に表示されるエラー

 残念ながらマネージ・コードのクラスが、そのメンバにネイティブ・コードのクラスを持つことは許されていません。

 マネージ・コード(.NET)のクラスがネイティブ・コード(C++)のクラスを内包するときは、ネイティブ・コードのクラスのポインタでなくてはなりません。従って正しくは以下のようになります。

#ifndef COUNTERLIB_H__
#define COUNTERLIB_H__

class counter;

public ref class CounterLib {
  counter* counter_; // ネイティブ・コードのクラス(※ポインタ
public:
  CounterLib(); // コンストラクタ
 ~CounterLib(); // デストラクタ
 !CounterLib(); // ファイナライザ
  void Increment();
  property int Value { int get(); }
};

#endif
.NETダイナミック・ライブラリのC++/CLIヘッダ・ファイル(counterlib.h)
ネイティブ・コードのクラスのポインタとして記述する必要がある。

 このヘッダに対する実装は簡単です。

 CounterLibクラスのコンストラクタ(CounterLib())でネイティブ・コードのオブジェクト(以下、ネイティブ・オブジェクト)を生成(new)し、デストラクタ(~CounterLib())はそのままファイナライザ(!CounterLib())を呼び出し、ファイナライザではネイティブ・オブジェクトを解放(delete)します。.NETの世界ではデストラクタは必ず呼び出されるとは限りませんから、デストラクタ内ではネイティブ・オブジェクトをdeleteし損ねることがあるからです。

 IncrementメソッドやValueプロパティでは、それぞれに対応したcounterクラスのメソッドを呼び出せばいいでしょう。

#include "counterlib.h"
#include "counter.h"

CounterLib::CounterLib() {
  counter_ = new counter(); // ネイティブ・オブジェクト生成
}

CounterLib::~CounterLib() {
  this->!CounterLib(); // ファイナライザを呼ぶ
}

CounterLib::!CounterLib() {
  delete counter_; // ネイティブ・オブジェクト解放
}

void CounterLib::Increment() {
  counter_->increment();
}

int CounterLib::Value::get() {
  return counter_->value();
}
.NETダイナミック・ライブラリのC++/CLIソース・ファイル(counterlib.cpp)
Win32スタティック・ライブラリの薄いラッパーとなる。

 以上をビルドすれば、薄いラッパーとなる.NETダイナミック・ライブラリ「counterlib.dll」が生成されます。

●.NETアプリケーションからのライブラリ(C++クラス)の利用

 あとは先ほどのC言語の関数の場合と同じです。C#やVBで記述したマネージ・コードからcounterlibを介してネイティブ・コードのcounterクラスとそのメンバを呼び出せます。

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

文字コード変換

 マネージ・コードからネイティブ・コードを呼ぶ場合、悩ましいのが文字列です。.NETでの文字列(System.Stringクラス)はUnicodeベースであるのに対し、既存のC/C++ライブラリの多くがShift-JISやEUCなどのマルチバイト文字列をベースにしているため、両者間で文字コードの変換を行わなくてはなりません。


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

本日 月間