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

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

5.5.5 シーケンス型

(1)IDLマッピング

 IDL言語でシーケンス型sequenceを指定した場合、C++言語では、配列の最大個数(_maximum)、配列の使用個数(_length)、データ域のアドレス(_buffer)、リリースフラグ(_release)をprivateデータに持つクラス(シーケンスクラス)にマッピングされます。また、データ域(_buffer)の獲得関数(関数名は"モジュール名::インタフェース名::シーケンス名::allocbuf"。以降XX::allocbuf関数と呼ぶ)が生成されます。
 シーケンスクラスのインスタンスはnew(C++の演算子)で生成します。パラメタには、配列の最大個数、使用個数、データ域のアドレス(XX::allocbuf関数で獲得)、リリースフラグを指定します。
 以降では、以下のIDL定義例をもとに説明します。

IDL言語

  module ODsample{
      interface  seqtest{
          typedef sequence<long>  sampleseq; 
          sampleseq op1(in sampleseq seq1, out sampleseq seq2, 
                        inout sampleseq seq3 ); 
      };
  };

C++言語

  class sampleseq
  {
      public: 
         sampleseq();                   // デフォルトコンストラクタ
         sampleseq( CORBA::ULong max);  // maximumコンストラクタ
         sampleseq( CORBA::ULong max, 
                    CORBA::ULong length, 
                    CORBA::Long *data, 
                    CORBA::Boolean release = CORBA_FALSE ); 
  // T *dataコンストラクタ
         sampleseq( const sampleseq &s ); 
                                        // コピーコンストラクタ
         ~sampleseq();                  // デストラクタ

         static CORBA::Long *allocbuf( CORBA::ULong ); 
                                       // allocbuf
         static void freebuf( CORBA::Long* ); 
                                       // freebuf

         sampleseq &operator=( const sampleseq &s ); 
                                      // 代入演算子

         CORBA::ULong maximum() const; 
                                      // maximumアクセス関数

         void length( CORBA::ULong ); 
                                      // lengthアクセス関数
         CORBA::ULong length() const; 
                                      // lengthアクセス関数

         CORBA::Long &operator[]( CORBA::ULong index ); 
                                      // _bufferのindex番目の要素を取得
         const CORBA::Long &operator[]( CORBA::ULong index ) 
                                               const; 
                                      // _bufferのindex番目の要素を取得

     private: 
         CORBA::ULong _maximum;        // 配列の最大個数
         CORBA::ULong _length;         // 配列の個数
         CORBA::Long *_buffer;         // 配列の値
         CORBA::Boolean _release;      // リリースフラグ
  };

// 左シフト代入演算子 void operator<<=( CORBA::Any&, const ODsample::seqtest::sampleseq& ); void operator<<=( CORBA::Any&, ODsample::seqtest::sampleseq* ); void operator<<=( CORBA::Any_var&, const ODsample::seqtest::sampleseq& ); // 右シフト代入演算子 CORBA::Boolean operator>>=( const CORBA::Any&, ODsample::seqtest::sampleseq*& ); CORBA::Boolean operator>>=( const CORBA::Any_var&, ODsample::seqtest::sampleseq*& );

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

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

パラメタ

サーバへ渡すパラメタ

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

in

領域を動的に獲得する場合は、new、XX::allocbuf関数を使用します。

inout

シーケンスクラスを動的に獲得する場合はnew(C++の演算子)を使用します。データ域を獲得する場合はXX::allocbuf関数を使用します。

リリースフラグにはCORBA_TRUEを設定してください。データ域はスタブで自動的に解放されます。

領域はスタブで自動的に獲得されます(構造体メンバも設定されます)。この際、獲得した領域にはリリースフラグにCORBA_TRUEが設定されます。

out
復帰

(inoutパラメタと同じ)

注意事項

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

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

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

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

      ODsample::sampleseq *seq = new ODsample::sampleseq(
          CORBA::ULong maximum, 
          CORBA::ULong minimum, 
          CORBA::Long *data, 
          CORBA::Boolean release = CORBA_FALSE ); 

      CORBA::Environment     env; 
      ODsample::seqtest_ptr  obj; 
      ODsample::sampleseq *seq0, *seq1, *seq2, *seq3; 

  // inパラメタ
      CORBA::Long *p = ODsample::seqtest::sampleseq::allocbuf(3); 
                                       // データ域獲得
      for( int i = 0; i < 3; i++ )     // データ域設定
          p[i] = i*10; 
                                       // インスタンス生成/パラメタ設定
      seq1 = new ODsample::seqtest::sampleseq( 3, 3, p, CORBA_TRUE ); 

  // inoutパラメタ
      CORBA::Long *q = ODsample::seqtest::sampleseq::allocbuf(5); 
                                       // データ域獲得
      for( i = 0; i < 5; i++ )         // データ域設定
          q[i] = i*100; 
                                       // インスタンス生成/パラメタ設定
      seq3 = new ODsample::seqtest::sampleseq( 5, 5, q, CORBA_TRUE ); 

  // サーバ呼出し
      seq0 = obj->op1( obj, *seq1, seq2, *seq3, env ); 

  // 領域解放
      delete seq0;                     // 復帰パラメタ
      delete seq1;                     // inパラメタ
      delete seq2;                     // outパラメタ
      delete seq3;                     // inoutパラメタ

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

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

パラメタ

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

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

in

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

inout

領域はスケルトンで自動的に獲得されます。この際、リリースフラグにはCORBA_TRUEが設定されます。

inoutデータの領域を更新する場合には、代入演算子でデータを複写します。
データ域はスケルトンで自動的に解放されます。

out
復帰値

シーケンスクラス・データ領域をnew,XX::allocbuf関数で獲得します。
リリースフラグにCORBA_TRUEを設定する場合、この領域はスケルトンで自動的に解放されます。
リリースフラグにCORBA_FALSEを設定する、またはリリースフラグを設定しない場合、スケルトンではデータ域の解放を行いません。この場合、不要になった時点で領域の解放処理を実施してください。

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

  ODsample::seqtest::sampleseq*
  ODsample_seqtest_impl::op1(
      const ODsample::seqtest::sampleseq  &seq1, 
      ODsample::seqtest::sampleseq        *&seq2, 
      ODsample::seqtest::sampleseq        &seq3, 
      CORBA::Environment                  &env ) 
      throw( CORBA::Exception ) 
  {
  // outパラメタ
      CORBA::Long *p = ODsample::seqtest::sampleseq::allocbuf(2); 
                                       // データ域獲得
      for( int i = 0; i < 2; i++ )     // データ域設定
          p[i] = i*1000; 
                                       // インスタンス生成/パラメタ設定
      seq2 = new ODsample::seqtest::sampleseq( 2, 2, p, CORBA_TRUE ); 

  // inoutパラメタ
      CORBA::Long *q = ODsample::seqtest::sampleseq::allocbuf(3); 
                                       // データ域獲得
      for( i = 0; i < 3; i++ )         // データ域設定
          q[i] = i; 
                                       // 代入演算子でパラメタ設定
      seq3 = ODsample::seqtest::sampleseq( 3, 3, q, CORBA_TRUE ); 

  // 復帰パラメタ
      CORBA::Long *r = ODsample::seqtest::sampleseq::allocbuf(1); 
      r[0] = 0;                        // データ域獲得/設定
                                       // インスタンス生成/パラメタ設定
      ODsample::seqtest::sampleseq_ptr seq = 
          new ODsample::seqtest::sampleseq( 1, 1, r, CORBA_TRUE ); 

      return seq; 
  }

(4)シーケンスクラスのメソッド

 シーケンスクラスで定義されているメソッドとその意味を以下に示します。

メソッド

意味

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

インスタンス生成時、シーケンス長_lengthを0で初期化します。また、サイズ指定ありのシーケンスの場合、最大長_maximumも0で初期化します。リリースフラグはCORBA_FALSEに設定します。

コピーコンストラクタ

インスタンス生成時、パラメタで指定された値を_length、_maximum、_bufferに設定します。リリースフラグはCORBA_TRUEに設定します。

maximumコンストラクタ

インスタンス生成時、サイズ指定なしのシーケンスの場合、最大長_maximumを0で初期化します。リリースフラグはCORBA_FALSEに設定します。

T*dataコンストラクタ

インスタンス生成時、サイズ指定あり/なしの両方で、パラメタで指定したシーケンス長、最大長、バッファポインタおよびリリースフラグを_length、_maximum、_buffer、_releaseに設定します。リリースフラグの指定を省略した場合はCORBA_FALSEを設定します。

デストラクタ

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

代入演算子

リリースフラグがCORBA_TRUEの場合、_bufferの値に対する領域を解放します。データ域の領域を獲得し代入元のデータを複写します。リリースフラグはCORBA_TRUEに設定します。

添字演算子

与えられたインデックスに対応する_bufferの内容を返します。

maximumアクセス関数

サイズ指定のないシーケンスの場合、現在使用可能なバッファの総数を返します。サイズが指定されたシーケンスの場合、IDLで与えられたシーケンスの大きさを返します。

lengthアクセス関数

length(ULong)関数はパラメタで指定した値をシーケンス長に設定します。length()はシーケンス長を返します。

allocbuf関数

T*dataコンストラクタに渡すことができるシーケンスの要素の配列を割り当てます。

freebuf関数

allocbuf関数によって割り当てられた配列を解放します。

左シフト代入演算子

AnyまたはAny_varへのシーケンスの代入を行います。Any変数のリリースフラグにはCORBA_TRUEを設定します。

右シフト代入演算子

AnyまたはAny_varからシーケンスへのポインタの取り出しを行います。

デフォルトコンストラク

 サイズ指定あり/なしの両方で、デフォルトコンストラクタはシーケンス長を0に初期化します。サイズ指定ありでは最大長はメンバイニシャライザで初期化されるので、アプリケーションは変更できません。サイズ指定なしのシーケンスでは、デフォルトコンストラクタで最大長を0に初期化します。いずれの場合もリリースフラグはCORBA_FALSEに設定されます。デフォルトコンストラクタの使用例と処理内容を以下に示します。

  // IDL
  typedef sequence< long > LongSeq1;  // サイズ指定なしの場合
  typedef sequence< long, 10 > LongSeq2; 
          // サイズ指定あり(この例では10)の場合

  //使用例
  LongSeq1 *seq1 = new LongSeq1();
          // 以下のデフォルトコンストラクタLongSeq1()が呼ばれ
          // seq1 が初期化されます。
  LongSeq2 *seq2 = new LongSeq2();
          // 以下のデフォルトコンストラクタLongSeq2()が呼ばれ
          // seq2 が初期化されます。

  // デフォルトコンストラクタ (サイズ 指定なし) 
  LongSeq1::LongSeq1()
  { 
      _length = 0; 
      _maximum = 0; 
      _release = CORBA_FALSE; 
  } 
  // デフォルトコンストラクタ(サイズ 指定あり) 
  LongSeq2::LongSeq2() : _maximum(10)        // IDLで指定したサイズ
  {  
      _length = 0; 
      _buffer = LongSeq2::allocbuf(10); 
      _release = CORBA_FALSE; 
  } 

コピーコンストラク

 コピーコンストラクタは、パラメタで指定されたシーケンスと同じ最大長と長さを持つ新しいシーケンスを生成し、パラメタで指定されたシーケンスの要素データをコピーします。コピーコンストラクタでは、リリースフラグはCORBA_TRUEに設定されます。コピーコンストラクタの使用例と処理内容を以下に示します。

  // 使用例
  long data[] = {1, 2, 3, 4, 5};
  LongSeq s1(10, 5, data); 
  LongSeq s2(s1)         // 以下のコピーコンストラクタが呼ばれs1の
                         // データがs2にコピーされます

  // コピーコンストラクタ
  LongSeq::LongSeq( const LongSeq &s ) 
  { 
      _length = s.length();
      _maximum = s.maximum();
      _buffer = allocbuf( _maximum ); 
      for( int i = 0; i < _length; i++ ) 
         // s の内容から *( _buffer + i ) へのコピー
      _release = CORBA_TRUE; 
  } 

maximumコンストラク

 サイズ指定なしのシーケンスで、最大長として指定された個数分の_bufferの領域を獲得するコンストラクタが提供されます。maximumコンストラクタはリリースフラグをCORBA_FALSEに設定します。maximumコンストラクタの使用例と処理内容を以下に示します。

  // IDL
  typedef sequence< long > LongSeq; 

  // 使用例
  LongSeq seq(10);     // 以下のmaximumコンストラクタ が呼ばれ
                       // seq の最大長が10に設定されます

  // maximumコンストラクタ
  LongSeq::LongSeq(ULong max) 
  { 
      _maximum = max; 
      _buffer = LongSeq::allocbuf(max); 
      release = CORBA_FALSE; 
  } 

T*dataコンストラク

 T*dataコンストラクタは、サイズ指定あり/なしの両方で、パラメタで指定した値をprivateデータに設定します。サイズ指定のないシーケンスに対しては最大長の設定も可能です。
 このコンストラクタは、releaseパラメタによって_bufferの扱いが異なります。パラメタがCORBA_FALSEである場合は、_bufferの指す領域はアプリケーションが管理する必要があります。一方、CORBA_TRUEである場合は、_bufferの指す領域はシーケンスクラスの変数が解放されるときに解放されます。T*dataコンストラクタの使用例と処理内容を以下に示します。

  // 使用例
  long data[] = {1, 2, 3, 4, 5};
  LongSeq seq = new LongSeq(10, 5, data); 
          // 以下のT *dataコンストラクタ が呼ばれseq が初期化されます

  // T *dataコンストラクタ
  LongSeq::LongSeq( ULong max, ULong length, Long *value, 
                                Boolean release = CORBA_FALSE )
  { 
      _length = length; 
      _maximum = max; 
      if( release ) {
          _buffer = allocbuf( _maximum ); 
          for( int i = 0; i < _length; i++ ) 
             *(  _buffer + i ) = *( value + i ); 
      } 
      else
          _buffer = value; 
      _release = release; 
  } 

 T *dataコンストラクタで指定するvalueの値がString型の場合はString_var*を渡し、オブジェクトリファレンス型の場合はObject_var*を渡します。

デストラク

  ODsample::seqtest::sampleseq::~sampleseq() 
  { 
      if( _release == CORBA_TRUE ) 
          ODsample::seqtest::sampleseq::freebuf( _buffer ); 
  }

代入演算

 代入演算子はリリースフラグがCORBA_TRUEに設定されている場合は_bufferの指す領域を解放し、パラメタで指定されたシーケンスの要素データをコピーします。代入演算子ではリリースフラグはCORBA_TRUEに設定されます。代入演算子の処理内容を以下に示します。

  // 使用例
  long data[] = {1, 2, 3, 4, 5};
  LongSeq s1(10, 5, data); 
  LongSeq s2; 

  LongSeq s2 = s1;    // 以下の代入演算子が呼ばれ、s1のデータがs2にコピーされます
  // 代入演算子
  LongSeq & 
  LongSeqV1::operator=( const LongSeqV1 &s ) 
  {
      if( _release ) 
          LongSeq::freebuf( _buffer ); 
      _length = s.length();
      _maximum = s.maximum();
      _buffer = LongSeq::allocbuf( _maximum ); 
      for( int i = 0; i < _length; i++ ) 
        //  *( _buffer + i )  へ s[i] をコピー
      _release =CORBA_TRUE; 
      return *this; 
  } 

添字演算

 添字演算子は、与えられたインデックスに対応する_bufferの内容を返します。添字演算子の使用例を以下に示します。

  // 使用例
  Long l; 
  long data[] = {1, 2, 3, 4, 5};
  LongSeq seq(10, 5, data,CORBA_TRUE); 

  l = seq[3];    // lの値は4 

 シーケンスの要素がString型の場合はString_varが返され、オブジェクトリファレンス型の場合はObject_var型が返されます。

maximumアクセス関

 サイズ指定のないシーケンスに対するmaximum()アクセス関数は、現在使用可能なバッファの総数を返します。アプリケーションは、サイズ指定のないシーケンスにどのくらいのアイテムが設定できるかを知ることができます。サイズが指定されたシーケンスに対するmaximum()はそのIDLで与えられたシーケンスの大きさを返します。maximumアクセス関数の使用例を以下に示します。

  // IDL
  typedef sequence< long > LongSeq1; 
  typedef sequence< long, 10 > LongSeq2; 

  // 使用例
  Long l; 
  LongSeq1 s1(5); 
  LongSeq2 s2; 

  l = s1.maximum();            // l の値は5 
  l = s2.maximum();            // l の値は10

lengthアクセス関

 length(ULong)関数はパラメタで指定した値をシーケンス長に設定し、また、_bufferにlength分の領域を獲得します。length()はシーケンス長を返します。lengthアクセス関数の使用例を以下に示します。

  // 使用例
  Long l; 
  long data[] = {1, 2, 3, 4, 5};
  LongSeq s1 = new LongSeq(10, 5, data,CORBA_TRUE); 

  l = s1->length();           // lの値は5 
  s1->length(6);              // シーケンス長を6 に設定

allocbuf関とfreebuf関

 allocbuf関数はT*dataコンストラクタに渡すことができるシーケンスの要素の配列を割り当てます。配列の長さはパラメタにより与えられます。使用例を以下に示します。

  // 使用例
  Long *data = LongSeq::allocbuf(3); 

  data[0] = 0; 
  data[1] = 1; 
  data[2] = 2; 

  LongSeq *seq = new LongSeq(10, 3, data, CORBA_TRUE); 

 allocbuf関数は要求されたメモリを割り当てられない場合はNULLポインタを返します。allocbuf関数によって割り当てられた配列は、リリースフラグがCORBA_TRUEの場合には、sequence解放時に、デストラクタにより解放されます。リリースフラグがCORBA_FALSEの場合にはfreebuf関数によって、アプリケーションにより解放しなければなりません。
 アプリケーションは、シーケンスを動的に割り当てるためにnewを、解放するためにdeleteを使うことができます。

左シフト代入演算

 左シフト代入演算子はAnyの_valueにシーケンスのコピーまたはポインタを代入します。このとき、AnyのリリースフラグにはCORBA_TRUEが設定されます。
 シーケンスのコピーの代入は、Any_varに対しても実行できます。使用例を以下に示します。

  // 使用例
  long data1[] = {1, 2, 3, 4, 5};
  ODsample::seqtest::sampleseq *seq1 = new ODsample::seqtest::sampleseq( 10, 5, data1 ); 
  CORBA::Any a1; 
  a1 <<= *seq1;  // a1の_valueにseq1のコピーを設定
                 // TypeCodeに_tc_ODsample_seqtest_sampleseq、リリースフラグにCORBA_TRUEを設定

  long data2[] = {1, 2, 3, 4};
  ODsample::seqtest::sampleseq *seq2 = new ODsample::seqtest::sampleseq( 10, 4, data2 ); 
  CORBA::Any a2; 
  a2 <<= seq2;   // a2の_valueにseq2のポインタを設定
                 // TypeCodeに_tc_ODsample_seqtest_sampleseq、リリースフラグにCORBA_TRUEを設定
                 // seq2を解放後は、a2の_valueにはアクセス不可

  long data3[] = {1, 2, 3};
  ODsample::seqtest::sampleseq *seq3 = new ODsample::seqtest::sampleseq( 10, 3, data3 ); 
  Any a3; 
  Any_var a3_v( &a3 ); 
  a3_v <<= *seq3; // a3の_valueにseq3のコピーを設定
                  // TypeCodeに_tc_ODsample_seqtest_sampleseq、リリースフラグにCORBA_TRUEを設定

右シフト代入演算

 右シフト代入演算子はAnyの_valueに設定されているシーケンスを取り出します。引数としてシーケンスのポインタを設定します。AnyのTypeCodeが引数のTypeCodeと等しければ_valueの値を引数に代入し、CORBA_TRUEで復帰します。
 右シフト代入演算子はAny_varに対しても使用できます。使用例を以下に示します。

  // 使用例
  long data[] = {1, 2, 3, 4, 5};
  ODsample::seqtest::sampleseq *seq1 = new ODsample::seqtest::sampleseq (10, 5, data); 

  Any a; 
  a <<= *seq1; // aの_valueにseq1のコピーを設定
               // TypeCodeに_tc_ODsample_seqtest_sampleseq、リリースフラグにCORBA_TRUEを設定

  ODsample::seqtest::sampleseq *seq2, *seq3;
  if( a >>= seq2 ){      // aのTypeCodeが_tc_ODsample_seqtest_sampleseqの場合、
                         // CORBA_TRUEを返し、seq2にaの_valueの値(seq1)を代入
  }

  Any_var a_var( &a );
  if( a_var >>= seq3 ){  // aのTypeCodeが_tc_ODsample_seqtest_sampleseqの場合、
                         // CORBA_TRUEを返し、seq3にaの_valueの値(seq1)を代入
  }

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

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