2006-02-27

C++/CLIによるインターフェイスクラスの使い方  [by miyachi]

以前にC++でboost::shared_ptrを使ってインターフェイスクラスを書くと言う事を書いたが、今回はそれのC++/CLI版。C++/CLIでは新たに interface が導入されJavaライクなインターフェイスが定義できるようになっている。またC++/CLIのマネージコードではガベージコレクションされるので gcnew と生成すれば破棄は自動的に行われるのでboost::shared_ptrも不要だ。早速サンプル。

// インターフェイスクラス
interface class IName {
public:
 virtual String ^ getName();
};

// 実装クラス
ref class Name : public IName {
public:
 Name( const std::string name )
 {
  a_name = gcnew String( name.c_str() );
 }
 virtual String ^ getName()
 {
  return a_name;
 }
private:
 String ^ a_name;
};

// ファクトリー関数
IName ^ makeName( const std::string name )
{
 IName ^ name_ptr = gcnew Name( name );
 return name_ptr;
}

// 使い方
void printName()
{
 std::string myname = "miyachi";
 IName ^ name_ptr = makeName( myname );
 Console::WriteLine( "Name = " + name_ptr->getName() + Environment::NewLine );
}


C++/CLIのマネージコードの世界ではStringを使う。内部はJavaと同じくユニコードになるので単純にcharポインタには変換できないので注意が必要。charポインタを使って初期化は出来る。

サンプルを見ると判るが、インターフェイスクラスにはinterfaceを付けて宣言をして、実装クラスにはrefを付けてマネージコードである事を宣言しておく。ただ細かくは実装クラスのメンバメソッドにもvirtualを付けなければいけなかったりする。

このサンプルを見るとC++/CLIと言うのはもう従来のネイティブなC++とは別物だと判る。コンソール出力もstd::coutだと.NETのStringが使え無いのでConsole::WriteLineを使わねばならない。

C#はマネージコードだけで済むなら便利だ、C++/CLIはネイティブコードとマネージコードの混在が可能なのが便利だ、ただしいずれにせよC++な世界とは言えないので移植性面では多大な問題があるだろう。C#やC++/CLIがどこまで広まるかが鍵となるが、.NET環境以外でこれらの言語を使えるようになるのだろうか?ちなみにMacOSの世界だとまた別言語となるObjective-C++なんてものもあるんだが… 困ったもんですねえ(^^;
2006-02-27 12:56:15 - miyachi - - [プログラミング] -

2006-02-23

C#とC++/CLI  [by miyachi]

実は今C#を使ったプログラムを使っている。C#を使えばMSの世界にどっぷりハマる事は明確なのでこれまで正直言って避けていたのだ。しかし仕事とあっては避けてばかりもいられないので色々と勉強をしている(^^;

最初の難関はGUI部だ。Visual-C++でMFCを使った開発ならもう10年選手なのでお手の物。でもC#を使ったイベントドリブンなGUI開発は今更食指も動かないし細かなノウハウも使え無いのでパスしたいところ。ならC++(ネイティブコード)からC#(マネージコード)が使えれば良い。私のC#に関する知識はJavaの真似っ子と言うレベル。Javaはバイトコードと呼ばれる中間コードを仮想マシンVMで実行するが、C#はマネージコードと呼ばれる中間コードになるだけだろうと。JavaならJNIを使ってネイティブコードとインターフェイスを取るがC#だとDllImportを使えば良いのかと考えていた。ただ今回必要なのはネイティブコードから中間コードを使いたいので本当は逆向きだ。実はちょっと面倒だなと敬遠しかかっていた。

ところが先方から「Visual Studio .NET 2003のC++マネージ拡張」と言うのがあるがどうだ?とのメールが。チェックして見るとうわ~何だこれは(^^; .NET 2003ではC++マネージ拡張となっているが、最新のVisual Studio .NET 2005 を使えば C++/CLI と言うC++を拡張してマネージコードを吐ける規格が出来ているでは無いか。しかも1つのソースファイル中でも#pragmaを使ってマネージコードとネイティブコードが使い分けられる。さすがMS節操が無いぞ(笑) しかもフレームワークとしてもMFCと.NET Frameworkが同時に使えてしまう。何でもアリやなあ… Java環境だとネイティブのインターフェイスはJNIだけなので使いにくいがこれも色々理由があってそうなっているので、MSの実装が素晴らしいのかとんでも無いのかは立場によって異論があるところでしょう。

と言う事で細かな技術的な問題点はあるもののとりあえずネイティブコードとマネージコードの混在は可能なようだ。C++/CLIが使えるのは Visual Studio .NET 2005 からなので、これからは2005を中心に使うか。でも C++/CLI なんてのが動いてしまうと C# の立場はどーなる(^^;;

あと注意が必要なのはC++/CLIはC++の拡張であって上位互換しか無い点と、ソースはほぼ同じに見えるがC++/CLIだとマネージコードになるのでメモリ管理が従来のネイティブコードのC++とは全く別物になるので気をつけないとコンパイル時にエラーになる辺り。この辺りの注意点なんかはまた時間を見て書きたいと思います。とりあえず今日はこの辺りまで。
2006-02-23 13:51:21 - miyachi - - [プログラミング] -

2006-02-10

プルダウン付きのツールバー  [by miyachi]

え~先日から書いているWin32でのツールバーシリーズ(笑) 今日のお題はIEやFireFoxなんかでも使われているツールバーにプルダウンのリストなんかのボタン以外のパーツを置く方法。

MFCのツールバークラス CToolBarCtrl で標準で設定できるのは、ボタン(TBSTYLE_BUTTON)とチェックボタン(TBSTYLE_CHECK)とセパレータ(TBSTYLE_SEP)の3種類のみ。ではどうするかと言えばセパレータを1つ指定して横幅を変更してその上にプルダウン等のパーツ(例:CComboBox)を乗っけてしまう事で実現する。

この方法で問題は無いのだが、ベースになるのがセパレータなのでプルダウンの高さがツールバーより小さい場合は余計な縦棒が背景に表示されてしまう。これを防ぐ方法を検索したが見つからないので力技でツールバーとプルダウンの間に空のテキストウィンドウ(CStatic)を置く事でクリアした。
 CToolBarCtrl m_TBar;
 (ツールバーの初期化は省略/セパレータをcmdidで生成しておく)
 // セパレータの幅を変更する
 CRect rect;
 const int nComboWidth = 110; // コンボボックスの幅
 TBBUTTONINFO tbbi;
 ZeroMemory( &tbbi, sizeof(tbbi) );
 tbbi.dwMask = TBIF_SIZE;
 tbbi.cbSize = sizeof(tbbi);
 tbbi.cx = nComboWidth + 4;
 m_TBar.SetButtonInfo( cmdid, &tbbi ); // cmdidはindexとは違う
 // 縦棒を塗りつぶす為のテキスト領域
 CStatic m_Base;
 m_TBar.GetItemRect( index, &rect ); // ここはindex(何番目)で指定
 m_Base.Create( "", WS_VISIBLE , rect, &m_TBar, 0 );
 // コンボボックスの生成
 CComboBox m_Combo;
 rect.top += 4; // 適当に上からの位置を指定
 rect.left += 2; // 開始位置もずらす
 m_Combo.Create(
  CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | WS_VISIBLE | WS_TABSTOP,
  rect, &m_TBar, 1 );
 // 必要ならこの後でフォントやリスト文字列をセットする
以上参考になれば幸いです :-)

さて先日「1ギガiPod nanoが登場―shuffleは値下げ」のアナウンスが。512MBのshuffleなら7900円か…う~むジム用に買ってしまいそうな値段になったぞ… CDを2~3枚を買うと思えば買えなくも無い(^^;;
2006-02-10 12:52:04 - miyachi - - [プログラミング] -