"その存在意義に疑問を抱きながらmanaged C++を弄る" archive

December 1, 2003

その存在意義に疑問を抱きながらmanaged C++を弄る
第二話のおまけ

 閑話休題。

 タイトルに「その存在意義に疑問を抱きながら」と入っているように、実際には、こんなものを書いている僕自身、managed C++にどれほどの有用性があるかは疑問を感じています。
 僕が卒研で作るシステムにmanaged C++を使っているもっとも大きな理由は、これを使うことによってC#とC++のシームレスな連携が可能になるからです。たしかにこれはmanaged C++の大きな利点ではあるのですが、実際には、わざわざC#、あるいはVB.NETやJ#.NETとC++を併用することが検討されるプログラムなんて数少ないでしょう。今回managed C++を使うに至った流れはここにある通りなのですが、現在の情勢だと、僕のような立場であればMFCを使うのが自然な選択です。わざわざC# & .NET frameworkを使おうとするのは僕の個人的な趣味によるところが大きく、この組み合わせでシステムを書くというのは他人に勧められるものではありません。
 事実、その普及の度合いを見れば、managed C++が世のプログラマたちに受け入れられていないのは明らかです。googleのヒット数も少ないし、BBSでもちっとも話題になっていない。日本のプログラマにとっては、日本語で読める本が一冊もないというのが痛いです(部分的に章を割いて触れられている本ならいくつかあるのですが)。
 
 何故managed C++は使われないのでしょう。まず、言語仕様が非常に入り組み、分かりにくいものになってしまっていることがあります。managed C++はC++に対してオブジェクト試行的な拡張(抽象クラス、インターフェース、イベントetcのサポート)と.NET対応のための拡張(.NET framework、ガベージコレクタ、ボクシングetcのサポート)とを施した言語ですが、C++との整合性の維持のためか、複雑で扱いづらい言語になっていると感じます。まだ僕自身がmanaged C++の言語仕様をあまり理解できていないということもあり、コンパイル時に思いも寄らない箇所でエラーが出て、その意味が分からずに悩まされることが多々あります。
 また、わざわざ拡張したにもかかわらず、.NETへの親和性はC#、VB.NETに比べて低いと言わざるを得ません。特にフォームデザイナを使えないのが致命的で、コードレベルでGUIを作る煩雑さを考えるだけで使う気が起きないという人は多いとおもいます。.NETを新しく勉強しようとするときに、言語にmanaged C++を選択するひとがほとんど居ないのもやむを得ないというところでしょう。反面、C#はJavaを模倣してMicrosoftが新しく作った言語で、過去の余計な遺産を引きずることもなく、.NETとの高い親和性を持っていますから。
 加えて、C#やVB.NETに比べてオフィシャル・アンオフィシャルの両面でドキュメントの数が少ないことや、言語自体の将来が正直あやしい(VisualJ++のようになるのではないか?)こともあるでしょう。

 結局、少なくとも現状では、managed C++を使う理由は、
  ・既存のC/C++で書かれたコードを.NETに移植したい
  ・Win32APIとの親和性の高さを活かしたい
 といった限定的なものになってしまうというのが結論です。ただ、個人的には面白い言語だと思うし、現在のような位置に居るのは残念だと感じます。

#それにしても、ですます調は書きにくくて疲れる。それに、ですます調はより読者の存在を意識した文体で、こんなほとんど読まれない文章に使うことはないという感じ。次回からは元に戻そうっと。

Post a comment to 'その存在意義に疑問を抱きながらmanaged C++を弄る
第二話のおまけ'



その存在意義に疑問を抱きながらmanaged C++を弄る
第二話 〜(unmanaged)C++なクラスを.NETに組み込んでみよう!〜

 さて、和書の一冊も発刊されず、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")

Post a comment to 'その存在意義に疑問を抱きながらmanaged C++を弄る
第二話 〜(unmanaged)C++なクラスを.NETに組み込んでみよう!〜'



November 21, 2003

その存在意義に疑問を抱きながらmanaged c++を弄る

卒研で動画像解析なシステムを書く。その開発環境をどうしようかと考えた。
先ず、ラスタ画像を扱うローレベルな処理が入るので、速いコード(よりマシンのネイティブコードに近いコード)を吐けなくてはならない。そこでC++を使うことが決定。環境としては、もっともマルチメディア対応が優れており、ライブラリが充実しているということで、Windowsを使おう。と、ここまではすんなり決まった。
ところで、C++はいちおう高級言語に位置づけられるくせに、実際的な処理が言語自体にほとんど用意されていない。高レベルな処理はすべて外部ライブラリとして用意する仕組みになっている。当然、細々とした処理をいちいち自前で書きたくないし、GUIをWindowsAPIで書くのも面倒でだるいので、ライブラリを使おうということになる。
ここでスタンダードな選択肢として登場するのはMFCなんだが、僕はMFCがあまり好きくない。そこで、前々からきちんと勉強してみようと思っていた.NET Frameworkを使うことにした。GUIその他を.NET Framework+C#で書いて、そこからC++で書かれたローレベルなコードを呼び出すようにしよう。そうだそうだそうしよう。

で。
C#からC++なコードを呼び出す手段としては、次のようなものがある。
 1. DLL(Dynamic Link Library)をつくる
 2. COM/ATLをつかう
しかし、関数ベースなDLLはオブジェクト指向化された.NETの世界観にそぐわないし、COM/ATLはこれから.NETに置き換えられていくレガシーな技術である。こいつらを使うのはいやーんな感じだ。そこでもう一つの選択肢が登場する。
 3. managed c++を使う
なんと、managed c++を中継役として経由することで、C#からC++のコードをシームレスに呼び出すことができるんである。
managed c++はそれ自体マイナーな存在で、プログラムを組むひとでも、多くは名前すら聞いたことがないんじゃないかとおもう。そこで、次回は、実際にmanage c++を使って、(unmanagedな)C++で書かれたコードを.NETな環境に移植するのを実際にやってみよう。

Post a comment to 'その存在意義に疑問を抱きながらmanaged c++を弄る'