| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
さて、和書の一冊も発刊されず、2chのスレッドは完全に寂れ、いまや当のMicrosoftですらその存在を覚えているのかが疑われる不遇な言語、managed C++のお時間です。
今回は、managed C++を使う一例として、また、C++なコードとC#なコードを連携させるケーススタディとして、C++で書かれた既存のクラスを、.NETな環境に移植するっていうのをやってみましょう。
C++なコードをシームレスにC#から呼び出せるさまには、おそらく貴方も感動を覚えるはずです……たぶん。また、VS.NET、そしてC#やmanaged C++をまったく使ったことがなくても、コードを追っていけば、何をやっているのかは余裕で分かると思います。(でも、その有り難みや面白さはいまいち伝わらないかも知れませんが)
それでは始めましょう。先ず、C++で書かれたクラスを用意します。これはC++でのコンパイルが通るものなら何でもOK。今回は、テスト用に書いた小さなクラスを使いました。メッセージボックスを表示するだけの関数をたった一つ持つという、わざわざクラス化する意味もない簡潔なクラスです。
#include <windows.h> class CTestClass { public: CTestClass() {}; ~CTestClass() {}; void DoSomething() { MessageBox(NULL, "ほげほげ", "", MB_OK); } }; |
次に、VS.NETを開いてソリューションを作成し、その下にmanaged C++のプロジェクトを作ります。[新しいプロジェクト]ダイアログを開き、[Visual C++プロジェクト]の中の[Managed C++クラスライブラリ]を選択してください。作成できたら、C++で書かれたクラスをプロジェクトに追加しましょう。

続いて、追加したC++クラスのwrapperを、managed C++で書きます。VS.NETによって、プロジェクトと同名のヘッダファイルが自動的に作られているので、簡便のため、今回はこれを編集します。自動的に作成された時点でのヘッダファイルは以下のようになっています。
#pragma once using namespace System; namespace My { public __gc class Class1 { // TODO: このクラスの、ユーザーのメソッドをここに追加してください。 }; } |
こいつをちょちょいといじくって、CTestClassクラスのwrapperをmanaged C++で書いてやります。
CTestClassクラスをプリプロセッサでincludeしてやり、namespaceの中にクラスを書きましょう。ここでは、"using"や"__gc"の意味を知る必要はありません。さらっと流してしまってOKです。興味がある人はwebやVS.NETのリファレンスでしらべてみてください。
書き換えたヘッダファイルは以下のようになります。
#pragma once #include "TestClass.h" using namespace System; namespace Testspace { public __gc class TestClass { private: CTestClass *tc; public: TestClass() { tc = new CTestClass(); } ~TestClass() { delete tc; } void DoSomething() { tc->DoSomething(); } }; } |
それでは、プロジェクトをビルドしてください。見事通れば(たぶん通るはずです)、managed C++側のコーディングはこれでおしまい。ひとまず、クラスライブラリの完成です。では、これを実際にC#から呼び出してみましょう。
ソリューションにC#なプロジェクトを追加します。[ファイル]->[プロジェクトの追加]->[新しいプロジェクト]からダイアログを呼び出し、プロジェクトを追加してください。テンプレートは[Windowsアプリケーション]あたりがよろしいでしょう。
追加されたプロジェクトに、managed C++で作成したクラスライブラリへの参照を設定します。ソリューションエクスプローラで、C#プロジェクトの中の[参照設定]からホップアップメニューを呼び出し、[参照の追加]を選択してください。ダイアログが表示されますので、[プロジェクト]タブを選択し、リストボックスのなかのmanaged C++なプロジェクトをダブルクリックしましょう。以下のようになったら、OKボタンをクリック。これで、managed C++で作成したクラスライブラリを、C#から利用できるようになります。

プロジェクトエクスプローラで、参照設定に新しく参照が追加されたことを確認してください。

では、さっそくC#から作成したクラスライブラリを呼び出して見ましょう。フォームデザイナを使って、自動的に追加されたフォームにボタンを配置し、Clickイベントにコードを追加してみました。
  private void button1_Click(object sender, System.EventArgs e) { Testspace.TestClass tc = new Testspace.TestClass(); tc.DoSomething(); } |
これをビルドし、実行してみます。結果はご覧の通り。

C++で書かれたコードを、C#から呼び出し、実行できていることが分かります。それがどうした、と言われてしまいそうですが、これは実はとてもハイパーで素敵なことなのです。C++とC#とを、一つのプログラム(VS.NETの言葉で言うとソリューション)のなかで同時に扱うことができているという点に注目してください。そもそも、C++はネイティブコードに、C#はVMの中間言語にコンパイルされます。しかし、いままでの手順を見ても分かるとおり、そんな差異をプログラマはまったく意識することなく、実装をおこなうことができます。
DLLやCOMのような面倒な手続きを必要とせずに、C#とC++とを連携させることができることには大きな利点があります。C#とC++とを併用することによって、ひいてはC#から.NET Frameworkを呼び出し、C++からWin32APIを呼び出すというようなライブラリの使い分けをすることによって、各々の適正に応じた処理の切り分けをすることができます。managed C++を仲立ちとすることで、C#とC++をスムースに統合した開発が可能になるということは、非常に興味深く、また検討に値するソリューションであると言えるでしょう。
というわけで、第二話はこれでお仕舞い。次回、第三話では、managed C++の言語仕様を概観してみようと思います。オブジェクト指向的に進化した言語仕様や、追加された沢山の予約語について、サンプルコードを挙げながら解説します。さらには.NETの中でのその位置付けについて考察をしてみましょう。
=========================================
追記(2004/06/08)
VisualStudio.NETなら上のやり方で大丈夫なのですが、VisualStudio.NET2003ではビルドに失敗するとおもいます。これはVS.NETがバージョンアップした際に、「C++クラスライブラリ」プロジェクトのデフォルト状態で"msvcrt.lib"および"msvcrtd.lib"をリンクしないようになったためです。これらのlibはC言語の標準ライブラリで、managed C++だけを使う限りではリンクする必要がないため、リンクしないような設定に変更されたのだとおもわれます。
VisualStudio.NET2003でビルドを通すには、プロジェクトの設定で上の2つのlibをリンクするようにするか、プリプロセッサとして次の2行をソースコードに追加してください。
#pragma comment(lib, "msvcrt.lib") #pragma comment(lib, "msvcrtd.lib") |

