動的起動インタフェースでサーバアプリケーションを呼び出す場合の例について説明します。
■初期化
初期化処理として、ORBのオブジェクトリファレンスを取得します。オブジェクトリファレンスを取得するには、初期化メソッドを呼び出します。
記述例を以下に示します。
main(argc, argv ) int argc; char *argv[]; { CORBA::ORB_ptr orb; // ORBのオブジェクトリファレンス CORBA::Environment_ptr env; // 例外情報 int current_argc = argc; env = new CORBA::Environment; // 例外情報 orb = CORBA::ORB_init(current_argc, argv, FJ_OM_ORBid, *env); : }
■ネーミングサービスのオブジェクトリファレンスの獲得
実行するオブジェクトをネーミングサービスから検索するために、ネーミングサービスのオブジェクトリファレンスを取得します。ネーミングサービスのオブジェクトリファレンスには、CORBAインタフェースのオブジェクトリファレンスの取り出しメソッドを使用します。
処理の記述例を以下に示します。
// NamingServiceのオブジェクトリファレンスを獲得 CORBA::Object_ptr obj = orb->resolve_initial_references( CORBA_ORB_ObjectId_NameService, *env ); // NamingContextクラスへの変換 CosNaming::NamingContext_ptr NamingContext_obj = CosNaming::NamingContext::_narrow( obj ); CORBA::release(obj);
■インタフェースリポジトリのサーバアプリケーション情報の獲得
インタフェースリポジトリには、IDLで定義されたモジュール名、インタフェース名、オペレーション名、およびパラメタが階層構造で格納されています。インタフェースリポジトリからサーバアプリケーションの情報を獲得する方法について、以下に示します。
インタフェースリポジトリからサーバアプリケーションの情報を取得するためには、InterfaceDefオブジェクトのオブジェクトリファレンスが必要です。InterfaceDefオブジェクトのオブジェクトリファレンスを求めるには、オブジェクト名をパラメタとして、ネーミングサービスからサーバアプリケーションのオブジェクトリファレンスを求めたあと、CORBA_Object::get::interface()メソッドにより、InterfaceDefオブジェクトリファレンスを取得します。
処理の記述例を以下に示します。
CORBA::Object_ptr obj; // オブジェクトリファレンス格納域 CosNaming::Name_ptr name; // CosNaming::Nameのインスタンス CosNaming::NameComponent_var *name_component; // オブジェクト名格納域 // CosNaming::NameComponent_var領域の獲得 name_component = CosNaming::Name::allocbuf(1); name_component[0]->id = (const CORBA::Char *)"ODdemo::calculator"; // オブジェクト名 name_component[0]->kind = (const CORBA::Char *)""; // オブジェクトのタイプ name = new CosNaming::Name(1,1,name_component,CORBA_TRUE ); // CosNaming::Name領域の獲得 // サーバアプリケーションのオブジェクトリファレンスを獲得 obj = NamingContext_obj-> resolve( *name, *env ); // InterfaceDefオブジェクトリファレンス取得 CORBA::InterfaceDef_ptr intf = obj->_get_interface( *env );
サーバアプリケーションのメソッド名をパラメタとして、CORBA::InterfaceDef::lookup_name()メソッドを使用することにより、インタフェースリポジトリから指定されたメソッドを検索します。結果として、指定したメソッド情報が格納されたOperationDefオブジェクトのオブジェクトリファレンスが通知されます。
// メソッドのOperationDefオブジェクトリファレンス取得 CORBA::ContainedSeq_ptr intf_opr = intf->lookup_name( "calculate", // メソッド名 -1, CORBA::dk_Operation, // Operation情報の取得 CORBA_FALSE, *env ); // OperationDefクラスへの変換 CORBA::OperationDef_ptr OperationDef_obj = CORBA::OperationDef::_narrow((*intf_opr)[0]);
OperationDefオブジェクトリファレンスをパラメタとして、CORBA::OperationDef::describe()メソッドにより、サーバアプリケーションがもっているメソッドのパラメタの情報(パラメタの名前、個数、パラメタの型など)をインタフェースリポジトリから検索します。
// 指定されたメソッドのパラメタ情報を検索 CORBA::Contained::Description *description = OperationDef_obj->describe( *env );
トランザクションを開始するために、Currentインタフェースのオブジェクトリファレンスを取得し、CosTransactions::Current::beginメソッドを呼び出します。
処理の記述例を以下に示します。
CosTransactions::Current_ptr Current; /* トランザクション開始オブジェクトリファレンス */ /* トランザクション開始インタフェースのオブジェクトリファレンスを獲得 */ obj = orb->resolve_initial_refarences( CORBA_ORB_ObjectId_TransactionCurrent, *env); Current = CosTransactions::Current::_narrow(obj); /* トランザクション開始メソッドの呼出し */ Current->begin(*env);
サーバアプリケーションに渡すパラメタを格納するための領域を保持するリストオブジェクトを生成するために、CORBA::ORB::create_list()メソッドに、何個のパラメタを格納するかを指定します。これにより、NVListオブジェクトリファレンスが通知されます。処理の記述例を以下に示します。
// Contained_Description構造体からパラメタ情報構造体の抽出 CORBA::Any tmp_any = *description->value; CORBA::OperationDescription *opr_description = (CORBA::OperationDescription *)tmp_any.value(); // パラメタ情報の抽出 CORBA::ParDescriptionSeq *params = opr_description->parameters; CORBA::NVList *arg_list; // NVList orb->create_list( params->length(), arg_list, *env ); // リストオブジェクトの生成
CORBA_NVListオブジェクトリファレンス、サーバアプリケーションのパラメタの名前、型、値、および長さをパラメタとしてCORBA::NVList::add_value()メソッドにより、サーバアプリケーションに渡すパラメタをリストオブジェクトに設定します。
処理の記述例を以下に示します。
CORBA::Any p1, p2; CORBA::Long x = 10, y = 20; p1 <<= x; p2 <<= y; // パラメタの設定 arg_list->add_value( ((*params)[0])->name, // パラメタ名 p1, // パラメタの型および値 CORBA::ARG_IN, // パラメタのタイプ(in,out, inout) *env ); // パラメタの設定 arg_list->add_value( ((*params)[1])->name, // パラメタ名 p2, // パラメタの型および値 CORBA::ARG_IN, // パラメタのタイプ(in,out, inout) *env );
CORBA::Object::create_request()メソッドにより、リクエストオブジェクトを作成します。リクエストとは、メソッド名にパラメタを加えたものです。リクエストオブジェクトに対して、サーバオブジェクトのオブジェクトリファレンス、NVListオブジェクトリファレンス、後述するNamedValueと呼ぶサーバの処理結果を格納する領域を指定することによりリクエストオブジェクトのオブジェクトリファレンスが通知されます。
処理の記述例を以下に示します。
CORBA::NVList_ptr arg_tmp; // 復帰パラメタ用リストオブジェクトの生成 orb->create_list(1, arg_tmp, *env); ODdemo::calculator::result *res = NULL; CORBA::Any any_tmp( _tc_ODdemo_calculator_result, res, CORBA_FALSE ); // 結果用受取り用変数(CORBA::NamedValue型変数) CORBA::NamedValue_ptr result = arg_tmp->add_value( NULL, // resultの設定 any_tmp, (CORBA::Flags)0, *env); CORBA::Request_ptr request; // リクエストオブジェクトの生成 obj->_create_request( CORBA_OBJECT_NIL, // context "calculate", // メソッド名 arg_list, // 入力パラメタ result, // 復帰値 request, // 出力パラメタの格納域 CORBA::OUT_LIST_MEMORY, *env );
NamedValueは、サーバの処理結果を格納するための領域です。
システムで定義する定義例を以下に示します。
module CORBA { struct NamedValue { identifier name; // パラメタの名前 any argument; // パラメタの値 long len; // パラメタの長さ Flags arg_modes; // パラメタの引き渡し方法(in,out,inout) }; };
class CORBA { class NamedValue { public: const char *name(CORBA::Environment &) const; // パラメタの名前 Any *value(CORBA::Environment &) const; // パラメタの値 Flags flags(CORBA::Environment &) const; // パラメタの引き渡し方法(in,out,inout) }; };
サーバアプリケーションに対してリクエストを送信します。リクエストの方法として、以下の方法があります。
同期送信
非同期送信
それぞれについて、以下に示します。
リクエストオブジェクトのオブジェクトリファレンスをパラメタとして、CORBA::Request::invoke()メソッドにより、サーバアプリケーションを呼び出します。処理の記述例を以下に示します。
request->invoke( *env );
リクエストオブジェクトのオブジェクトリファレンスをパラメタとして、CORBA::Request::send_deferred()メソッドにより、サーバアプリケーションを呼び出します。サーバアプリケーションの処理結果は、CORBA::Request:get_response()メソッドにより受け取ります。
処理の記述例を以下に示します。
request->send_deferred( *env ); // 処理の要求 request->get_response( *env ); // 処理結果の受取り
CORBA::Request::get_response()サーバアプリケーションからリクエストが完了していないことが判明した場合、再度CORBA::Request::get_response()メソッドを呼び出します。
リクエストオブジェクトのオブジェクトリファレンスをパラメタとして、CORBA::release()関数により、リクエストオブジェクトを削除します。また、同様にNVListオブジェクトのオブジェクトリファレンスをパラメタとしてCORBA::release()関数により、NVListオブジェクト削除をします。
処理の記述例を以下に示します。
CORBA::release( request ); // リクエストオブジェクトの削除 CORBA::release( arg_list); // NVListオブジェクトの削除
■トランザクションの完了
サーバアプリケーションのメソッド呼出しの結果を復帰状態から判断し、トランザクションの状態を決定します。トランザクションを正常終了する場合は、CosTransactions::Current::commitメソッドを呼び出し、トランザクションをコミットします。トランザクションを異常終了する場合は、CosTransactions::Current::rollbackメソッドを呼び出し、トランザクションをロールバックします。
処理の記述例を以下に示します。
/* サーバアプリケーションのメソッド呼出しの復帰状態を確認 */ if(env->exception()) Current->rollback(*env); else Current->commit(CORBA_TRUE, *env);