reverse_ref);counter_refは,PortableServer_POA_servant_to_reference()で取得した参照。oaf_active_server_register()にIDLを渡すと例外が発生する。--oaf-activate-iid=OAFIID:ReverseCouふむ動く。サーバーが二つ動いているのは上手くない。CORBAを利用しているのだから,できてほしいところ。Bonoboは直感的に言ってプロセスを跨いでgtk+オブジェクトを扱うことはすでに述べた。今日はサーバープロセスで動作するgtk+オブジェクトをクライアントプロセスで表示させよう。GTK_WINDOW(window);}これだけ。スタンドアローンの場合と異なるのは次の二つの関数だけ。bonobo_ui_container_new();BonoboUIContainerインスタンスが何をするものかはまだ調べてない。ソースにもあるように,IIDをbonobo_widget_new_control()に与えると,内部でサーバーに接続し,サーバーgtk+オブジェクトを取得できる。クライアントはこのオブジェクトがどのようなメソッド,シグナルを持っているかコンパイル時には何も知らない。このサーバーに特有のメソッドを呼びたい場合はコンパイル時に知る必要がある。サーバーgtk+オブジェクトを取得すると,ローカルなオブジェクトと区別することなく扱える。サーバーでの描画はネットワークを介してクライアントプロセスのウィンドウに表示される。BONOBO_OBJECT(control);}これだけ。widgetを生成し,show()してからbonobo_control_new()に渡すだけ。クライアント側で表示するだけならwidget自体に特別な仕掛けは何も必要ない。HORB-IIOPクライアントでは次のようなコードになる。printf(".\n");単純に関数を呼び出すだけのようだが,内部でORBitがメソッド,引数をバイト列に変換してサーバーへ送り,サーバーで再び関数呼び出しに戻す。サーバーでは次のようになる。Counter_DATA(servant)->value++;}サーバーの戻り値は,やはりORBitによってネットワークを介してクライアントに届けられる。ORBitによるCORBAサーバーの実装CORBAではオブジェクトを識別するのにIORを用いる。ネームサーバーを用いて活性化しているサーバーへ接続できる。サーバープロセスをクライアントが起動することができない(よねぇ?)ので,あらかじめサーバープロセスを起動しておく必要がある。これでは不便なので,GNOMEではliboafが名前からサーバーを検索し,必要があればサーバープロセスを起動する。サーバープロセスへのパスを記述する。.oafinfoファイルはXMLで記述する。</oaf_server></oaf_info>IID属性値がCORBAオブジェクトを識別する文字列。本来は"OAFIID:プログラム名:UUID"という形式だが,手を抜いている。あるサーバープロセスが異なるインターフェイスを持つ複数のオブジェクトを提供したい場合,type属性値が"factory"のoaf_server要素を並べることになる。オブジェクトの提供するインターフェイスを変更(追加を含む)した場合は,以前のIIDによるサーバーを登録したまま,異なるIIDを持つサーバーを追加して登録するか,提供するインターフェイスを追加し(.oafinfoファイルではrepo_ids以下にitem要素を加える),動的に新しいインターフェイスを提供することで互換性を維持する。同じIIDのままインターフェイスを変更してはならない。OAFによるサーバーの検索Bonobo/OAFOAFではスクリプトから利用しやすい別名はない。次のようなスクリプトがある。10]機械としてはCLSIDでも変わらないだろうが,スクリプトに書くときは多少難儀か。何にしても,クライアントからはIIDを与えれば後はOAFがよきに計らってくれる。OAF/ORBitを用いれば,IIDによってCORBAサーバープロセスを起動し,CORBAサービスを受けることができる。GNOMEではこの仕組みの上にBonoboを設けている。単純に言えば,Bonoboはプロセスを跨いでgtk+オブジェクトを動作させる。Bonoboを用いると,クライアントを修正することなく,扱えるコンポーネントを追加することができる。今日はを多少補足する。オブジェクトを使い終わったら,クライアントでは次の関数を呼び出す。object);サーバーがBonobo::Unknown派生の場合,サーバーに通知され,サーバー側でオブジェクトを破棄することができる。Bonobo::Unknown派生でない場合もBonoboObject化することはできるが,この場合はunrefしてもサーバーには何も通知されない。サーバーでは,生成したオブジェクトに"destroy"シグナルを接続しておく。オブジェクトを生成するところを示す。NULL);こうしておくと,クライアントでオブジェクトが不要になったときに"destroy"シグナルハンドラで対処することができる。gtk_main_quit();サーバーでは,提供するサービスによるが,オブジェクトが全て破棄されたときにプロセスを終了するようにしてもよい。クライアントが再びサービスを必要としたときにOAFがサーバープロセスを起動してくれる。えーっと,昨日の表現は正しくない。COMコントロール版のMyClockでもCMyClockCtrlクラスは具象クラスであるCOleControlから派生している。もってCOleControlはCWndから派生している。MFCではCOleControlクラスがIOleControl実装クラスのインスタンスを所有するようになってる。Bonoboも考え方としては同じデザイン。Bonoboサーバーの実装では,BonoboObject(GtkObjectのサブクラス)またはそのサブクラスから派生させてサーバークラスを生成し,CORBAインターフェイスの実装はそのサーバークラスに所有させるようにする。Bonoboでは,サーバーは独立したプロセスで,機械を跨がないシステム内でもWindowsのようにDLLではない。サーバー・プロセスはリモートオブジェクトの工場(factory)として動作する。oafinfoファイルを次のように記述する。</oaf_server></oaf_info>クライアントからIIDとして"OAFIID:Counter:20001114"を与えると,OAFは恐らく次のように動作するのだろう。oafinfoファイルを調べ,与えられたIIDのOAFサーバーを探す。type属性の属性値がfactoryなので,location属性で与えられるIIDを持つOAFサーバーを探すCounterFactoryサーバーのtypeはexeなので,locationを実行。oaf_flags);クライアントのコードを示す。0;}BonoboはGtk+を内部で使うので,ウィンドウを開かなくてもgtk+の初期化が必要なことに注意しよう。それ以外はクライアント側はかなり単純。Bonoboではfactoryクラスを介してサーバーを呼び出す。0;}サーバーを実装する場合に,いちいちGNOME::ObjectFactoryインターフェイスを実装する必要はない。その辺はBonoboがやってくれる。GNOME::ObjectFactoryはGNOME::GenericFactoryの発展したものともいえる。GNOME::GenericFactoryはlibgnorbaで用いるが,今では使われない,ように思う。次の関数にFactoryクラスのIIDとコールバック関数を与えればいい。data);クライアント(直接的にはOAF)から新しいリモートオブジェクトの生成するよう呼ばれた場合は,コールバック関数が呼ばれる。obj;}恐らく,クライアントの目的のオブジェクトの選択だとかがここに入ることになるはずだが,今回は一つしかないので盲目的にCounterオブジェクトを生成している。BonoboObjectオブジェクトもbonobo_object_new_from_servant()関数でBonoboに生成してもらえる。