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

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

5.5.7 共用体

(1)IDLマッピング

 IDL言語で共用体unionを指定した場合、C++言語ではデータ型を識別する弁別情報_dと共用体データ域_ptrから構成される共用体クラスにマッピングされます。
 以降では、以下のIDL定義例をもとに説明します。

IDL言語

  module ODsample{
      union samplefix switch(long){    // 共用体(固定長) 
          case 1: long    para1; 
          case 2: long    para2; 
      };
      union samplevar switch(long){    // 共用体(可変長) 
          case 1: long    para1; 
          case 2: string  para2; 
      };
      interface  uniontest{
          samplefix  op2(
                         in samplefix uni1, 
                         out samplefix uni2, 
                         inout samplefix uni3
          ); 
          samplevar  op1(
                         in samplevar uni1, 
                         out samplevar uni2, 
                         inout samplevar uni3
          ); 
      };
  };

C++言語

  class samplefix
  {
      public: 
          samplefix();                   // デフォルトコンストラクタ
          samplefix( const samplefix& ); // コピーコンストラクタ
          ~samplefix();                  // デストラクタ

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

          void   _d( CORBA::Long );    // 弁別子情報の設定
          CORBA::Long  _d() const;     // 弁別子情報の取得

          void   para1( CORBA::Long ); // para1データの設定
          CORBA::Long  para1() const;  // para1データの取得

          void   para2( CORBA::Long );  // para2データの設定
          CORBA::Long  para2() const;   // para2データの取得

      private: 
          CORBA::Long  __d;             // 弁別情報
          void         *_ptr;           // データ域
  };

  class samplevar
  {
      public: 
          samplevar();                        // デフォルトコンストラクタ
          samplevar( const samplevar& );      // コピーコンストラクタ
          ~samplevar();                       // デストラクタ

          samplevar &operator=( const samplevar & ); 
                                              // 代入演算子
          // 弁別子アクセス関数
          void    _d( CORBA::Long );          // 弁別子情報の設定
          CORBA::Long    _d() const;          // 弁別子情報の取得
          // メンバアクセス関数
          void   para1( CORBA::Long );        // para1データの設定
          CORBA::Long    para1() const;       // para1データの取得

          void   para2( CORBA::Char* );       // para2データの設定
          void   para2( const CORBA::Char* ); // para2データの設定
          void   para2( const CORBA::String_var& ); 
                                              // para2データの設定
          CORBA::Char *   para2() const;      // para2データの取得

      private: 
          CORBA::Long    __d;                 // 弁別情報
          void           *_ptr;               // データ格納域
  };

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

 共用体(固定長)のパラメタ(in、out、inout)を扱う場合、宣言した共用体変数をパラメタに指定します。領域の獲得/解放を行う必要はありません。データ型識別情報、データ値をメンバ関数を使って設定します。
 以下にクライアントアプリケーションでの処理例を示します。

      ODsample::uniontest_ptr    obj; 
      ODsample::samplefix        unif0, unif1, unif2, unif3; 
      CORBA::Environment         env; 

      unif1.para2(100);                   // inパラメタの設定
      unif3.para1(200);                   // inoutパラメタの設定

  // サーバ呼出し
      unif0 = obj->op2( unif1, unif2, unif3, env );

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

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

パラメタ

サーバへ渡すパラメタ

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

in

可変長データ域を動的に獲得する場合は、newを使用します。

inout

(inパラメタと同じ)

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

out
復帰値

(inoutパラメタと同じ)

注意事項

 クライアントおよびスタブで動的に獲得した領域は、不要になった時点でdelete(C++演算子)で解放する必要があります。deleteを発行すると、構造体の可変長データの領域も解放されます。

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

      ODsample::uniontest_ptr      obj;
      ODsample::samplevar          *uni0, uni1, *uni2, uni3;
      CORBA::Environment           env;

      uni1.para1(10);              // inパラメタ設定
      uni3.para2( (const CORBA::Char *)"INOUT::para2" );
                                   // inoutパラメタ設定

  // サーバ呼出し
      uni0 = obj->op1(  uni1, uni2, uni3, env ); 
                                  
  // 領域解放
      CORBA_free( uni0 );          // 復帰パラメタ
      CORBA_free( uni2 );          // outパラメタ

(4)サーバアプリケーションで扱うパラメタ(固定長)

 共用体(固定長)のout、inoutパラメタを扱う場合、データ型の識別情報とデータの値をメンバ関数を使って共用体クラスのインスタンスに設定します。共用体の領域の獲得/解放を行う必要はありません。

  ODsample::samplefix
  ODsample_uniontest_impl::op2(
      const ODsample::samplefix  &uni1, 
      ODsample::samplefix        &uni2, 
      ODsample::samplefix        &uni3, 
      CORBA::Environment         &env 
   ) 
  throw( CORBA::Exception ) 
  {
  // outパラメタの処理
      uni2.para1(10);             // データの値の設定

  // inoutパラメタの処理
      uni3.para2(100);            // データの値の設定

  // 復帰値の処理
      ODsample::samplefix uni; 
      uni.para1(100);             // データの値の設定
      return( uni ); 
  }

(5)サーバアプリケーションで扱うパラメタ(可変長)

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

パラメタ

クライアントからのパラメタ領域

クライアントへのパラメタ領域

in

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

inout

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

メンバアクセス関数で新しいデータを設定します(古い領域は自動的に解放されます)。
可変長データの場合はデータ域獲得関数でデータ域を獲得します。
この領域はスケルトンで自動的に解放されます。

out
復帰値

new/データ域獲得関数で共用体領域/可変長データ域を獲得します。
この領域はスケルトンで自動的に解放されます。

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

  ODsample_samplevar *
  ODsample_uniontest_impl::op1(
      const ODsample::samplevar  &uni1, 
      ODsample::samplevar        *&uni2, 
      ODsample::samplevar        &uni3, 
      CORBA::Environment         &env ) 
  {
  // outパラメタ
      uni2 = new ODsample::samplevar;                     // 領域獲得
      uni2->para2( (const CORBA::Char *)"OUT::param" );   // パラメタ設定

  // inoutパラメタ
      uni3.para1(10);                                     // パラメタ設定

  // 復帰パラメタ
      ODsample::samplevar *uni = ODsample::samplevar;     // 領域獲得
      uni.para1(30);                                      // パラメタ設定

      return( uni ); 
  }

(6)共用体クラスのメソッド

 共用体クラスで定義されているメソッドと意味を以下に示します。

シーケンスクラスのメンバ

意味

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

インスタンス生成時、データ格納域_ptrを0で初期化します。

コピーコンストラクタ

インスタンス生成時、パラメタで指定された値を_ptr、_dに設定します。

デストラクタ

インスタンス破壊時、_ptr、_dの値に対する領域を解放します。

代入演算子

パラメタで指定された値を_ptr、_dに設定します。

弁別子アクセス関数

_d(Long)関数はパラメタで指定した値を弁別子に設定します。
_d()は弁別子を返します。

メンバアクセス関数

"メンバ名(変数)"の形式で呼び出すことによりメンバの値をデータ格納域に設定します。
"メンバ名()"の形式で呼び出すことによりデータ格納域の設定されている変数の値を取得します。

デフォルトコンストラク

 デフォルトコンストラクタは、データ格納域_ptrを0に初期化します。デフォルトコンストラクタの使用例と処理内容を以下に示します。

  // IDL
  union UnionSmp switch(long){ 
      case 1: long para1; 
      case 2: string para2; 
  };

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

  // デフォルトコンストラクタ 
  UnionSmp::UnionSmp()
  { 
      _ptr = (void *)0; 
  } 

コピーコンストラク

 コピーコンストラクタは、パラメタで指定された共用体のデータ__d(弁別情報)、_ptr(データ格納域)のデータを複写します。コピーコンストラクタの使用例と処理内容を以下に示します。

  // IDL
  union UnionSmp switch(long){ 
      case 1: long para1; 
      case 2: string para2; 
  };

  // 使用例
  UnionSmp *uni1 = new UnionSmp();
  uni1->para1(10); // メンバアクセス関数
  UnionSmp uni2 = new UnionSmp(*uni1); 
                   // コピーコンストラクタにより、_dに1、_ptrに値10が設定されます

  // コピーコンストラクタ
  UnionSample::UnionSmp(const UnionSmp &_UnionSmp ) 
  {
      switch( _UnionSmp.__d ) {
         case 1: 
             para1( _UnionSmp.para1() ); 
             break; 
         case 2: 
             para2( (const CORBA::Char *)_UnionSmp.para2); 
             break; 
      }
      __d = _UnionSmp._d();
  } 

デストラク

 デストラクタは、_ptrの領域を解放します。デストラクタの使用例を以下に示します。

  // IDL
  union UnionSmp switch(long){ 
      case 1: long para1; 
      case 2: string para2; 
  };

  // 使用例
  UnionSmp *uni1 = new UnionSmp();
  CORBA::Char *str = CORBA::string_alloc(5); 
  strcpy( str, "data"); 
  uni1->para2(str);    // 共用体メンバ関数。strのポインタが_ptrに渡されます

  delete  uni1;        // デストラクタが呼ばれ_ptr(str)の領域も解放されます。

代入演算

  // IDL
  union UnionSmp switch(long){ 
      case 1: long para1; 
      case 2: string para2; 
  };

  // 使用例
  UnionSmp *uni1 = new UnionSmp(); 
  uni1->para1(10);     // メンバアクセス関数 
  UnionSmp uni2 = *uni1;
                   // 代入演算子により、uni2の_dに1、_ptrに値10が設定されます。

  // 代入演算子
  パラメタで指定された値を_ptr,_dに設定します。

  UnionSmp& 
  UnionSmp::operator=( const UnionSmp &_UnionSmp ) 
  { 
      if( _ptr ){ 
          switch( __d ){ 
          case    1 : 
          { 
              delete _ptr; 
              _ptr = 0; 
           } 
           break; 
           case    2 : 
           { 
               CORBA::String_var       *_tmp = ( CORBA::String_var* )_ptr; 
               delete _tmp; 
               _ptr = 0; 
           } 
           } 
      } 
      switch( _UnionSmp.__d ){ 
          case 1: 
                  para1( _UnionSmp.para1() ); 
          case 2: 
                  para2( (const CORBA::Char *)_UnionSmp.para2() ); 
                  break; 
      } 
      __d = _UnionSmp._d(); 
      return *this; 
  } 

弁別子アクセス関

 弁別子アクセス関数は、弁別情報(__d)への設定および弁別情報獲得のためのメンバ関数です。弁別子アクセス関数の使用例と処理内容を以下に示します。

  // IDL
  union UnionSmp switch(long){ 
      case 1: long para1; 
      case 2: string para2; 
  };

  // 使用例
  UnionSmp *uni1 = new UnionSmp();
  uni1->para1(10); 
  CORBA::Long l = uni1->_d();    // lの値は1
  uni1->_d(2);                   // __dに2が設定されます。
  l = uni1->_d();                // lの値は2

メンバアクセス関

 メンバアクセス関数は、メンバ設定関数とメンバ取得関数が提供されます(関数名はメンバ名と同じ)。メンバアクセス関数の使用例と処理内容を以下に示します。

  // IDL
  typedef long Bytes[64]; 
  struct S {
      long len; 
  };

  union UnionSmp switch(long){ 
      case 1: long x; 
      case 2: Bytes y; 
      case 3: string z; 
      case 4: S w; 
  };

  // 使用例
  UnionSmp *uni1 = new UnionSmp();
  uni1->x(10); // メンバ設定関数。__dに1、_ptrに値10が設定されます。

  UnionSmp *uni2 = new UnionSmp();
  Bytes data; 
  for ( int i = 0; i < 64; i++ ) 
      data[i] = i; 
  uni2->y(data);          // __dに2、_ptrにdataを複写します。

  UnionSmp uni3(*uni2); 
  Bytes_slice *slice = uni3->y();  // _ptrに設定されているポインタを返します。

  UnionSmp uni4; 
  CORBA::Char *str = CORBA::string_alloc(4); 
  strcpy( str, "ZZZ" ); 
  uni4.z( str );          // __dに3、_ptrにstrのポインタを設定します。
  uni4.z( (const CORBA::Char *)"XXX" ); 
           // _ptrに設定されている領域を解放し、データ"XXX"を複写します
           // (const付き:データの複写,なし:ポインタ渡し) 

  UnionSmp  uni5; 
  S  str_data; 
  str_data.len = 5; 
  uni5.w( data_len );     // __dに4、_ptrにdata_lenを複写します。
  S  str_data2; 
  str_data2 = uni5.w();   // str_data2に_ptrに設定されているデータが複写されます。

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

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