ページの先頭行へ戻る
Interstage Application Server アプリケーション作成ガイド(データベース連携サービス編)
Interstage

3.8.2 ソースプログラムの作成(動的起動インタフェース)

動的起動インタフェースでサーバアプリケーションを呼び出す場合の例について説明します。


■初期化

初期化処理として、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で定義されたモジュール名、インタフェース名、オペレーション名、およびパラメタが階層構造で格納されています。インタフェースリポジトリからサーバアプリケーションの情報を獲得する方法について、以下に示します。


(1) InterfaceDefオブジェクトリファレンスの獲得

インタフェースリポジトリからサーバアプリケーションの情報を取得するためには、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 );

(2) OperationDefオブジェクトリファレンスの取得

サーバアプリケーションのメソッド名をパラメタとして、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]);

(3) パラメタ情報の取得

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);

■パラメタの組み立て


(1) パラメタリストの生成

サーバアプリケーションに渡すパラメタを格納するための領域を保持するリストオブジェクトを生成するために、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 );  // リストオブジェクトの生成

(2) パラメタリストの設定

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は、サーバの処理結果を格納するための領域です。
システムで定義する定義例を以下に示します。


IDLファイルの定義例
module CORBA
{
    struct NamedValue
    {
        identifier      name;         // パラメタの名前
        any              argument;    // パラメタの値
        long             len;         // パラメタの長さ
        Flags          arg_modes;     // パラメタの引き渡し方法(in,out,inout)
    };
};

C++言語での定義例
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);