Interstage Application Server アプリケーション作成ガイド (CORBAサービス編) |
目次
索引
![]() ![]() |
第5章 アプリケーションの開発(C++言語) | > 5.5 データ型に対するマッピング |
IDL言語でシーケンス型sequenceを指定した場合、C++言語では、配列の最大個数(_maximum)、配列の使用個数(_length)、データ域のアドレス(_buffer)、リリースフラグ(_release)をprivateデータに持つクラス(シーケンスクラス)にマッピングされます。また、データ域(_buffer)の獲得関数(関数名は"モジュール名::インタフェース名::シーケンス名::allocbuf"。以降XX::allocbuf関数と呼ぶ)が生成されます。
シーケンスクラスのインスタンスはnew(C++の演算子)で生成します。パラメタには、配列の最大個数、使用個数、データ域のアドレス(XX::allocbuf関数で獲得)、リリースフラグを指定します。
以降では、以下のIDL定義例をもとに説明します。
module ODsample{ interface seqtest{ typedef sequence<long> sampleseq; sampleseq op1(in sampleseq seq1, out sampleseq seq2, inout sampleseq seq3 ); }; };
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; // リリースフラグ };
クライアントアプリケーションのパラメタの扱いについて、以下に示します。
パラメタ |
サーバへ渡すパラメタ |
サーバから渡されたパラメタ |
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に設定されます。
以下にクライアントアプリケーションの処理例を示します。
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パラメタ
サーバアプリケーションのパラメタの扱いについて、以下に示します。
パラメタ |
クライアントから渡されたパラメタ |
クライアントへ渡すパラメタ |
in |
領域はスケルトンで自動的に獲得/解放されます。 |
− |
inout |
領域はスケルトンで自動的に獲得されます。この際、リリースフラグにはCORBA_TRUEが設定されます。 |
inoutデータの領域を更新する場合には、代入演算子でデータを複写します。 |
out |
− |
シーケンスクラス・データ領域をnew,XX::allocbuf関数で獲得します。 |
以下にサーバアプリケーションでの処理例を示します。
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; }
シーケンスクラスで定義されているメソッドとその意味を以下に示します。
メソッド |
意味 |
デフォルトコンストラクタ |
インスタンス生成時、シーケンス長_lengthを0で初期化します。また、サイズ指定ありのシーケンスの場合、最大長_maximumも0で初期化します。 |
コピーコンストラクタ |
インスタンス生成時、パラメタで指定された値を_length、_maximum、_bufferに設定します。 |
maximumコンストラクタ |
インスタンス生成時、サイズ指定なしのシーケンスの場合、最大長_maximumを0で初期化します。 |
T*dataコンストラクタ |
インスタンス生成時、サイズ指定あり/なしの両方で、パラメタで指定したシーケンス長、最大長およびバッファポインタを_length、_maximum、_bufferに設定します。 |
デストラクタ |
インスタンス破壊時、_bufferの値に対する領域を解放します。 |
代入演算子 |
パラメタで指定された値を_bufferに設定します。 |
添字演算子 |
与えられたインデックスに対応する_bufferの内容を返します。 |
maximumアクセス関数 |
サイズ指定のないシーケンスの場合、現在使用可能なバッファの総数を返します。サイズが指定されたシーケンスの場合、IDLで与えられたシーケンスの大きさを返します。 |
lengthアクセス関数 |
length(ULong)関数はパラメタで指定した値をシーケンス長に設定します。length()はシーケンス長を返します。 |
allocbuf関数 |
T*dataコンストラクタに渡すことができるシーケンスの要素の配列を割り当てます。 |
freebuf関数 |
allocbuf関数によって割り当てられた配列を解放します。 |
サイズ指定あり/なしの両方で、デフォルトコンストラクタはシーケンス長を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; }
サイズ指定なしのシーケンスで、最大長として指定された個数分の_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コンストラクタは、サイズ指定あり/なしの両方で、パラメタで指定した値を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()はその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(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関数は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を使うことができます。
目次
索引
![]() ![]() |