17.5 DIIと一緒にIRを使用

DII Requestオブジェクトに取り込む必要がある情報ソースの一つは,IRです(「16. インタフェースリポジトリの使用」参照)。次に示すのは,IRを使用してオペレーションのパラメタを取得する場合の例です。この例は,実際のDIIアプリケーションでは一般的ではありませんが,リモートオブジェクトの型(Account)とそのメソッドの一つの名前(balance)を組み込み情報として持っています。実際のDIIアプリケーションでは,その情報をソースの外部,例えばユーザから取得します。

  • 任意のAccountオブジェクトにバインドします。
  • IRの中からAccountのbalanceメソッドを検索し,IRのOperationDefからオペレーションリストを作成します。
  • 引数と結果のコンポーネントを生成し,それらを_create_requestメソッドに引き渡します。balanceメソッドが例外を返さないことに注意してください。
  • Requestを起動し,結果を抽出して出力します。
コードサンプル17-25 IRとDIIの使用(C++)

// acctdii_ir.C
// This example illustrates IR and DII

#include <iostream.h>
#include "corba.h"

int main(int argc, char* const* argv) {
  CORBA::ORB_ptr orb;
  CORBA::Object_var account;

  CORBA::NamedValue_var result;
  CORBA::Any_ptr resultAny;
  CORBA::Request_var req;
  CORBA::NVList_var operation_list;

  CORBA::Any customer;
  CORBA::Float acct_balance;

try {
  // use argv[1] as the account name, or a default.
  CORBA::String_var name;
  if (argc == 2)
     name = (const char *) argv[1];
  else
     name = (const char *) "Default Name";
  try {
     // Initialize the ORB.
     orb = CORBA::ORB_init(argc, argv);
  } catch(const CORBA::Exception& excep) {
     cout << "Failure during ORB_init" << endl;
     cout << excep << endl;
     exit(1);
  }

  cout << "ORB_init succeeded" << endl;

  // Unlike traditional binds, this bind is called off of "orb"
  // and returns a generic object pointer based
  // on the interface name
  try {
     account = orb->bind("IDL:Account:1.0");
  } catch(const CORBA::Exception& excep) {
     cout << "Error binding to account" << endl;
     cout << excep << endl;
     exit(2);
  }

  cout << "Bound to account object" << endl;

  // Obtain Operation Description for the "balance" method of
  // the Account
  try {
     CORBA::InterfaceDef_var intf = account->_get_interface();
     if (intf == CORBA::InterfaceDef::_nil()) {
        cout << "Account returned a nil interface definition."
             << endl;
        cout << "Be sure an Interface Repository is
              running and"
             << endl;
        cout << "properly loaded" << endl;
        exit(3);
     }
     CORBA::Contained_var oper_container =
           intf->lookup("balance");
     CORBA::OperationDef_var oper_def =
     CORBA::OperationDef::_narrow(oper_container);
     orb->create_operation_list(
           oper_def, operation_list.out());

  } catch(const CORBA::Exception& excep) {
     cout << "Error while obtaining operation list" << endl;
     cout << excep << endl;
     exit(4);
  }

  // Create request that will be sent to the account object
  try {
     // Create placeholder for result
     orb->create_named_value(result.out());
     resultAny = result->value();
     resultAny->replace( CORBA::_tc_float, &result);

     // Set the argument value within the operation_list
     CORBA::NamedValue_ptr arg = operation_list->item(0);
     CORBA::Any_ptr anyArg = arg->value();
     *anyArg <<= (const char *) name;

     // Create the request
     account->_create_request(CORBA::Context::_nil(),
           "balance",
           operation_list,
           result,
           req.out(),
           0);

  } catch(const CORBA::Exception& excep) {
     cout << "Error while creating request" << endl;
     cout << excep << endl;
     exit(5);
  }

  // Execute the request
  try {
     req->invoke();
     CORBA::Environment_ptr env = req->env();
     if ( env->exception() ) {
        cout << "Exception occurred" << endl;
        cout << *(env->exception()) << endl;
        acct_balance = 0;
     } else {
        // Get the return value;
        acct_balance = *(CORBA::Float *)resultAny->value();
     }
  } catch(const CORBA::Exception& excep) {
     cout << "Error while invoking request" << endl;
     cout << excep << endl;
     exit(6);
  }

  // Print out the results
  cout << "The balance in " << name << "'s account is $";
  cout << acct_balance << "." << endl;
} catch ( const CORBA::Exception& excep ) {
  cout << "Error occurred" << endl;
  cout << excep << endl;
}