Interstage Application Server アプリケーション作成ガイド (CORBAサービス編)
目次 索引 前ページ次ページ

第5章 アプリケーションの開発(C++言語)> 5.5 データ型に対するマッピング

5.5.4 any型

(1)IDLマッピング

 IDL言語でany型を指定した場合、C++言語では、データ型を識別するTypeCode(_tc)、データ域のアドレス(_value)、リリースフラグ(_release)をprivateデータに持つCORBA::Anyクラスにマッピングされます。CORBA::Anyクラスのインスタンスはnew(C++の演算子)で生成します。privateデータのアクセスはCORBA::Anyクラスのメソッドを用います。インスタンス生成の記述形式を以下に示します。

  CORBA::Any  *data = new CORBA::Any(
          CORBA::TypeCode_ptr  _tc,        // データ型識別TypeCode
          void                 *_value,    // データ域アドレス
          CORBA::Boolean       release );  // リリースフラグ

IDL言語

  class CORBA {
      class Any {
          public: 
              Any();                                 // デフォルトコンストラクタ
              Any( const Any & );                    // コピーコンストラクタ
              Any( TypeCode_ptr tc, void *value, 
                Boolean release = CORBA_FALSE ); 
      // コンストラクタ(型定義されていない値用) 
              ~Any();                                // デストラクタ

              Any     &operator=( const Any & );     // 代入演算子
      // 左シフト代入演算子
              void    operator<<=( Short );          // Short型
              void    operator<<=( UShort );         // UShort型
              void    operator<<=( Long );           // Long型
              void    operator<<=( ULong );          // ULong型
              void    operator<<=( LongLong );       // LongLong型
              void    operator<<=( Float );          // Float型
              void    operator<<=( Double );         // Double型
              void    operator<<=( LongDouble );     // LongDouble型 (Windows(R)、Solaris OE のみ)
              void    operator<<=( const Any & );    // Any型
              void    operator<<=( const Char * );   // Char * (String) 型
              void    operator<<=( const WChar * );  // WChar * (WString) 型

// 右シフト代入演算子 Boolean operator>>=( Short & ) const; // Short型 Boolean operator>>=( UShort & ) const; // UShort型 Boolean operator>>=( Long & ) const; // Long型 Boolean operator>>=( ULong & ) const; // ULong型 Boolean operator>>=( LongLong & ) const; // LongLong型 Boolean operator>>=( Float & ) const; // Float型 Boolean operator>>=( Double & ) const; // Double型 Boolean operator>>=( LongDouble & ) const; // LongDouble型 (Windows(R)、Solaris OE のみ) Boolean operator>>=( Any & ) const; // Any型 Boolean operator>>=( Char *& ) const; // Char * (String) 型 Boolean operator>>=( WChar *& ) const; // WChar * (WString) 型
      // boolean, octet, char の設定に必要な特別な helper 型
              struct  from_boolean {
                  from_boolean( Boolean b ) : val(b) {}
                  Boolean    val; 
              };
              struct  from_octet {
                  from_octet( Octet o ) : val(o) {}
                  Octet      val; 
              };
              struct  from_char {
                  from_char( Char c ) : val(c) {}
                  Char       val; 
              };
              void    operator<<=( from_boolean ); 
              void    operator<<=( from_octet ); 
              void    operator<<=( from_char ); 
      // boolean, octet, char の抽出に必要な特別な helper 型
              struct  to_boolean {
                  to_boolean( Boolean &b ) : ref(b) {}
                  Boolean    &ref; 
              };
              struct  to_octet {
                 to_octet( Octet &o ) : ref(o) {}
                 Octet       &ref; 
              };
              struct  to_char {
                  to_char( Char &c ) : ref(c) {}
                  Char       &ref; 
              };
              Boolean operator>>=( to_boolean ) const; 
              Boolean operator>>=( to_octet ) const; 
              Boolean operator>>=( to_char ) const; 

              void  replace( TypeCode_ptr tc, void *value, 
                             Boolean release = CORBA_FALSE ); 

              TypeCode_ptr    type() const; 
              const  void     *value() const; 

              private: 
                  TypeCode_ptr    _tc;         // データ型識別TypeCode
                  void            *_value;     // データ域アドレス
                  Boolean         _release;    // リリースフラグ
      };
  };

 以降では、以下のany型のIDL定義例をもとに、クライアント/サーバアプリケーションの記述例を示します。

IDL言語

  module ODsample{
      struct sample1 {
          long    para1; 
          string  para2; 
      };
      struct sample2 {
          char    para1; 
          float   para2; 
      };
      struct sample3 {
          char    para1; 
          double  para2; 
      };
      interface  anytest{
          any    op1(in any any1, out any any2, inout any any3 ); 
      };
  };

(2)クライアントアプリケーションで扱うパラメタ

 クライアントアプリケーションのパラメタの扱いについて、以下に示します。

パラメタ

サーバへ渡すパラメタ

サーバから渡されたパラメタ

in

領域を動的に獲得する場合は、インスタンスをnewで生成します。

inout

(inパラメタと同じ)

領域はスタブで自動的に獲得されます。

out
復帰

(inoutパラメタと同じ)

注意事項

 クライアントおよびスタブで獲得した領域は、不要になった時点でdelete(C++演算子)で解放する必要があります。このとき、データ域(_value)を解放するかどうかをリリースフラグで指定します。リリースフラグの指定は、CORBA::Anyクラスのインスタンス生成時に3番目のパラメタで行います。

  CORBA_TRUE  : delete発行時、_valueの領域も解放される
  CORBA_FALSE : delete発行時、_valueの領域は解放されない(デフォルト)

 なお、スタブで獲得されたパラメタ(inout,out,復帰)のリリースフラグは、CORBA_TRUEに設定されます。リリースフラグの詳細については、“any型、sequence型のリリースフラグ”を参照してください。

 以下にクライアントアプリケーションの処理例を示します。

      CORBA::Environment     env; 
      ODsample::anytest_ptr  obj; 
      ODsample::sample1      *smp1; 
      ODsample::sample2      *smp2; 
      ODsample::sample3      *smp3; 
      CORBA::Any             *any0, *any1, *any2, *any3;

  // inパラメタ
      ODsample::sample2 *smp2 = new ODsample::sample2; 
                                       // データ域獲得(ODsample::sample2構造体)
      smp2->para1 = 'z';                // データ域(構造体)設定
      smp2->para2 = 0.001;
                                       // インスタンス生成/パラメタ設定
      any1 = new CORBA::Any( _tc_ODsample_sample2, smp2, CORBA_TRUE ); 

  // inoutパラメタ
      ODsample::sample3 *smp3 = new ODsample::sample3; 
                                       // データ域獲得(ODsample::sample3構造体)
      smp3->para1 = 'x';                // データ域(構造体)設定
      smp3->para2 = 0.0001;
      any3 = new CORBA::Any();         // インスタンス生成
                                       // パラメタ設定
      any3->replace( _tc_ODsample_sample3, smp3, CORBA_TRUE); 

  // サーバ呼出し
      any0 = obj->op1( *any1, any2, *any3, env ); 

  // 領域解放
      delete any0;                      // 復帰パラメタ
      delete any1;                     // inパラメタ
      delete any2;                     // outパラメタ
      delete any3;                     // inoutパラメタ

(3)サーバアプリケーションで扱うパラメタ

 サーバアプリケーションのパラメタの扱いについて、以下に示します。

パラメタ

クライアントから渡されたパラメタ

クライアントへ渡すパラメタ

in

領域はスケルトンで自動的に獲得/解放されます。

inout

領域はスケルトンで自動的に獲得されます。

replaceメソッドでデータを置き換えます。
この領域はスケルトンで自動的に解放されます。

out
復帰値

newで獲得します。
この領域はスケルトンで自動的に解放されます。

 以下にサーバアプリケーションでの処理例を示します。

  CORBA::Any*
  ODsample_anytest_impl::op1(
      const CORBA::Any   &any1, 
      CORBA::Any         *&any2, 
      CORBA::Any         &any3, 
      CORBA::Environment &env ) 
      throw( CORBA::Exception ) 
  {
  // outパラメタ
      ODsample::sample1 *smp1 = new ODsample::sample1; 
                                       // データ域獲得(ODsample::sample1構造体)
      smp1->para1 = 100;               // データ域(構造体)設定
      CORBA::Char *str = CORBA::string_alloc(3); 
      strcpy( str, "OUT" );
      smp1->para2 = str;
                                       // インスタンス生成/パラメタ設定
      any2 = new CORBA::Any( _tc_ODsample_sample1, smp1, CORBA_TRUE); 

  // inoutパラメタ
      ODsample::sample2 *smp2 = new ODsample::sample2; 
                                       // データ域獲得(ODsample::sample2構造体)
      smp2->para1 = 'x';                // データ域(構造体)設定
      smp2->para2 = 0.01;
                                       // パラメタ設定
      any3->replace( _tc_ODsample_sample2, smp2, CORBA_TRUE ); 

  // 復帰値の処理
      ODsample::sample3 *smp3 = new ODsample::sample3; 
                                       // データ域獲得(ODsample::sample3構造体)
      smp3->para1 = 'z';                // データ域(構造体)設定
      smp3->para2 = 0.001;
                                       // インスタンス生成/パラメタ設定
      CORBA::Any *any = new CORBA::Any( _tc_ODsample_sample3, smp3, CORBA_TRUE ); 

      return( any ); 
  }

(4)CORBA::Anyクラスのメソッド

 CORBA::Anyクラスで定義されているメソッドの意味を以下に示します。

CORBA::Anyクラスのメンバ

意味

デフォルトコンストラクタ

インスタンス生成時、_tcを0、_valueを0で初期化します。リリースフラグにはCORBA_FALSEが設定されます。

コピーコンストラクタ

インスタンス生成時、データ域用の領域を獲得し、パラメタで指定された値を複写します。リリースフラグにはCORBA_TRUEが設定されます。

コンストラクタ

インスタンス生成時、パラメタで指定された値を_tcと_valueに設定します。リリースフラグは指定された値が設定されます。リリースフラグの指定を省略した場合はCORBA_FALSEが設定されます。

デストラクタ

リリースフラグがCORBA_TRUEの場合、_tcと_valueの値に対する領域を解放します。

代入演算子

リリースフラグがCORBA_TRUEの場合、現在設定されている_tcと_valueの値に対する領域を解放します。その後、データ域用の領域を獲得し、パラメタで指定された値を設定します。リリースフラグにはCORBA_TRUEが設定されます。

左シフト代入演算子

リリースフラグがCORBA_TRUEの場合、現在設定されている_tcと_valueの値に対する領域を解放します。その後、データ域用の領域を獲得し、パラメタで指定された値を設定します。リリースフラグにはCORBA_TRUEが設定されます。

右シフト代入演算子

_valueに設定されている値を取り出します。

helper関数

boolean,char,octetの場合、unsigned charになるので、これらの型を識別します。

replace関数

リリースフラグがCORBA_TRUEの場合、現在設定されている_valueの値に対する領域を解放します。その後、パラメタで指定された値を_tcと_valueに設定します(新たに領域は獲得しません)。リリースフラグは指定された値が設定されます。リリースフラグの指定を省略した場合はCORBA_FALSEが設定されます。

type関数

_tcのTypeCodeオブジェクトのオブジェクトリファレンスを返します。

value関数

_valueに設定されているデータ域へのポインタをvoid*型で返します。

デフォルトコンストラク

 デフォルトコンストラクタは、_tcを0(TypeCode::_nil())、_valueを0で初期化し、また、リリースフラグをCORBA_TRUEに設定します。デフォルトコンストラクタの使用例と処理内容を以下に示します。

  // 使用例
  CORBA::Any a;                      // デフォルトコンストラクタで初期化

  または

  CORBA::Any *b = new CORBA::Any;    // デフォルトコンストラクタで初期化

  // デフォルトコンストラクタの処理内容
  Any::Any()
  { 
        _tc = TypeCode::_nil();
        _value = 0; 
        _release = CORBA_TRUE; 
  };

コピーコンストラク

 コピーコンストラクタの使用例と処理内容を以下に示します。

  // 使用例
  CORBA::Any a;           // デフォルトコンストラクタで初期化

  CORBA::Long x = 3; 
  a <<= x;                // 左シフト代入演算子。_tcに_tc_longを、
                          // _valueにCORBA::Longの領域を獲得し値3を設定、
                          // リリースフラグをCORBA_TRUEに設定

  CORBA::Any *b = new CORBA::Any(a); 
          // コピーコンストラクタにより、aのprivateデータ(_tc,_value)のデータを複写し、
          // また、リリースフラグをCORBA_TRUEに設定

  CORBA::Any c(*b);      // コピーコンストラクタ

  // コピーコンストラクタの処理内容
  Any::Any( const Any &a ) 
  { 
      _tc = TypeCode::_duplicate(a.type());
      _value = ...    // 領域を獲得し、aの_valueデータを複写する処理
      _release = CORBA_TRUE; 
  };

コンストラク

 このコンストラクタは、パラメタで指定したTypeCodeオブジェクトリファレンスtcの値をコピーし、valueの指すポインタを_valueに代入します。パラメタのreleaseがCORBA_TRUEであれば、デストラクタ起動時に_valueの指す領域は解放されます。release=CORBA_FALSEの場合は、アプリケーションが_valueでポイントされる領域を管理しなければなりません。

  // 使用例
  Long l = 1; 
  CORBA::Any *a = new CORBA::Any(tc_long, &l, CORBA_TRUE); 
                        // 以下のコンストラクタが呼ばれます。

  // コンストラクタの処理内容
  Any::Any( TypeCode_ptr tc, void *value, Boolean release = CORBA_FALSE) 
  {
      _tc = tc;
      _value = value; 
      _release = release; 
  }

デストラク

 デストラクタの使用例と処理内容を以下に示します。

  // 使用例
  void X()
  { 
      CORBA::Any *a = new CORBA::Any();

      CORBA::Long x = 3; 
      (*a) <<= x;  // 左シフト代入演算子

      delete a;    // デストラクタ
  }                         

  // デストラクタの処理内容
  Any::~Any()
  { 
      if( _release && _value ) 
          delete _value;  // リリースフラグが設定されている場合には削除
      CORBA::release( _tc ); 
  }

代入演算

 代入演算子の使用例と処理内容を以下に示します。

  // 使用例
  CORBA::Any a1;  // デフォルトコンストラクタで初期化
  CORBA::Any a2;  // デフォルトコンストラクタで初期化

  CORBA::Long x = 10; 
  a1 <<= x;       // 左シフト代入演算子で、_tcに_tc_longを、
                  // _valueにCORBA::Longの領域を獲得し値10を、
                  // リリースフラグにCORBA_TRUEを設定
  a2 = a1;        // 代入演算子で、a2の_valueにCORBA::Longの領域を獲得し、
                  // a1のデータ(_tc,_value)の値をa2に複写し、
                  // リリースフラグにCORBA_TRUEを設定

  // 代入演算子の処理内容
  Any & 
  Any::operator=( const Any &r ) 
  { 
      if( _release && _value ) 
          delete value;  // リリースフラグがCORBA_TRUEなら、既存データを削除
      CORBA::release( _tc ); 

      _tc = TypeCode::_duplicate(a.type());
      _value = ...       // 領域を獲得し、rの_valueの内容を複写する処理
      _release = CORBA_TRUE; 
      return this; 
  }

左シフト代入演算

 左シフト代入演算子の使用例と処理内容を以下に示します。

  // 使用例
  CORBA::Long value = 42; 
  Any a; 
  a <<= value;  // _tcに_tc_longを、_valueにCORBA::Longの領域を獲得し値42を、
                // リリースフラグにCORBA_TRUEを設定

  // 左シフト代入演算子の処理内容
  void CORBA::Any::operator<<=( Long v ) 
  {
      if( _release && _value ) 
          delete value;  // リリースフラグがCORBA_TRUEなら、既存データを削除
      CORBA::release( _tc ); 

      _tc = .... ( _tc_longを設定する処理) 
      _value = new Long(v);  // _valueにvの値を設定
      _release = CORBA_TRUE; 
  }

右シフト代入演算

 右シフト代入演算子の使用例と処理内容を以下に示します。

  // 使用例
  CORBA::Long value; 
  Any a; 
  a <<= CORBA::Long(42);  // aの_tcに_tc_longを_valueに値42を代入
                          // リリースフラグはCORBA_TRUEを設定
  if(a >>= value ) {
                          // aの_tcが_tc_longを指している場合には、CORBA_TRUEを返し、
                          // valueに_valueの値を代入。
  }

  // 右シフト代入演算子の処理内容
  CORBA::Boolean 
  CORBA::Any::operator>>=( Long &r )const
  {
      if( _tc->kind != tk_long )  // _tcがtc_longを指しているかチェック
          return CORBA_FALSE
      r = ...                     // _valueの値を代入する処理
      return CORBA_TRUE; 
  }

 文字列と配列に関して取り出された値を使うときは、文字列または配列のサイズ指定を超えてはいけないので、アプリケーションはAny型のTypeCodeをチェックしなければなりません。

helper関

 boolean、char、octetがすべてC++でunsigned charにマッピングされるので、以下のように、直接Any型変数にboolean、octet、char型の変数を代入または取り出しを行うとコンパイルエラーになります。

  Octet oct = 040; 
  Any any; 
  any <<= oct;                  // この行はコンパイルが通らない

 boolean, char, octetを区別する方法としてhelper関数と、operator<<=とoperator>>=が提供されます。helper関数の使用例を以下に示します。

  CORBA::Boolean b = CORBA_TRUE; 
  Any any; 
  any <<= CORBA::Any::from_boolean(b);  // _tcに_tc_booleanを、_valueにbの値を代入
    ... 
  if( any >>= CORBA::Any::to_boolean(b)){
      // anyの_valueはCORBA::Boolean型
      // bにanyの_valueの値(ここではCORBA_TRUE)を代入
  }

replace関

 replace関数は、パラメタで指定したTypeCodeオブジェクトリファレンスtcと値valueを_tcと_valueに代入します。パラメタのreleaseがCORBA_TRUEであれば、デストラクタ起動時に、_valueの指す領域を解放します。release=CORBA_FALSEの場合は、アプリケーションが_valueでポイントされる領域を解放しなければなりません。

  // 使用例
  Long l = 1;
  CORBA::Any *a = new CORBA::Any();

  a->replace(_tc_long, &l, CORBA_FALSE);    // 以下の関数が呼ばれます。

  // replace関数の処理内容
  Any::Any::replace( TypeCode_ptr tc, void *value, Boolean release = CORBA_FALSE)
  {
      if( _release && _value ) 
          delete value;  // リリースフラグがCORBA_TRUEなら、既存データを削除
      CORBA::release( _tc ); 

      _tc = tc;
      _value = value; 
      _release =  release; 
  }

type関

 type関数は、Anyに関連づけられたCORBA::TypeCodeオブジェクトのオブジェクトリファレンスCORBA::TypeCode_ptrを返します。

  CORBA::Any *a = new CORBA::Any();
  CORBA::Long x; 
  (*a) <<= x; 
    ... 
  CORBA::TypeCode_ptr tc = a->type(); // _tcを取り出します。
  if( tc->kind() == tk_long ){ 
         ...              // このプログラムでは、等しいためここが処理されます。
  }

value関

 value関数は、Any型変数に設定されている_valueをvoid*型で返します。_valueに値が設定されていなければNULLポインタを返します。

  CORBA::Any any; 
  CORBA::Long x; 
  x = 3; 
  any <<= x;     // 左シフト代入演算子で_tcに_tc_longを_valueに値3を代入

  CORBA::Long *p = (CORBA::Long *)any.value();
                 // _valueを取り出します。void*型なのでCORBA::Long *型にキャスト

  count << "(*p)=" << *p << endl;

目次 索引 前ページ次ページ

All Rights Reserved, Copyright(C) 富士通株式会社 2005