Borland(R) Enterprise Server VisiBroker(R) デベロッパーズガイド

[目次][索引][前へ][次へ]

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