Interstage Application Server アプリケーション作成ガイド (CORBAサービス編) |
目次
索引
![]() ![]() |
第5章 アプリケーションの開発(C++言語) | > 5.5 データ型に対するマッピング |
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 ); // リリースフラグ
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 のみ) 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 のみ) 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定義例をもとに、クライアント/サーバアプリケーションの記述例を示します。
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 ); }; };
クライアントアプリケーションのパラメタの扱いについて、以下に示します。
パラメタ |
サーバへ渡すパラメタ |
サーバから渡されたパラメタ |
in |
領域を動的に獲得する場合は、インスタンスをnewで生成します。 |
− |
inout |
(inパラメタと同じ) |
領域はスタブで自動的に獲得されます。 |
out |
− |
(inoutパラメタと同じ) |
クライアントおよびスタブで獲得した領域は、不要になった時点でdelete(C++演算子)で解放する必要があります。このとき、データ域(_value)を解放するかどうかをリリースフラグで指定します。リリースフラグの指定は、CORBA::Anyクラスのインスタンス生成時に3番目のパラメタで行います。
CORBA_TRUE : delete発行時、_valueの領域も解放される CORBA_FALSE : delete発行時、_valueの領域は解放されない(デフォルト)
なお、スタブで獲得されたパラメタ(out,復帰)のリリースフラグは、CORBA_TRUEに設定されます。
以下にクライアントアプリケーションの処理例を示します。
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パラメタ
サーバアプリケーションのパラメタの扱いについて、以下に示します。
パラメタ |
クライアントから渡されたパラメタ |
クライアントへ渡すパラメタ |
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 ); }
CORBA::Anyクラスで定義されているメソッドの意味を以下に示します。
CORBA::Anyクラスのメンバ |
意味 |
デフォルトコンストラクタ |
インスタンス生成時、_tcを0、_valueを0で初期化します。 |
コピーコンストラクタ |
インスタンス生成時、パラメタで指定された値を_tcと_valueに設定します。 |
コンストラクタ |
インスタンス生成時、パラメタで指定された値を_tcと_valueに設定します。 |
デストラクタ |
インスタンス破壊時、_tcと_valueの値に対する領域を解放します。 |
代入演算子 |
現在設定されている_tcと_valueの値に対する領域を解放し、パラメタで指定された値を設定します。 |
左シフト代入演算子 |
現在設定されている_valueの値に対する領域を解放し、パラメタで指定された値を_valueに設定します。 |
右シフト代入演算子 |
_valueに設定されている値を取り出します。 |
helper関数 |
boolean,char,octetの場合、unsigned charになるので、これらの型を識別します。 |
replace関数 |
パラメタで指定された値を_tcと_valueに設定します。 |
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に値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_longを設定する処理) _value = value; _release = release; }
デストラクタの使用例と処理内容を以下に示します。
// 使用例 void X() { CORBA::Any *a = new CORBA::Any(); CORBA.Long x = 3; (*a) <<= 3; // 左シフト代入演算子 delete a; // デストラクタ } // デストラクタの処理内容 Any:: ̄~Any() { TypeCode::_release _tc; if( _release && _value ) delete _value; // リリースフラグが設定されている場合には削除 }
代入演算子の使用例と処理内容を以下に示します。
// 使用例 CORBA::Any a1; // デフォルトコンストラクタで初期化 CORBA::Any a2; // デフォルトコンストラクタで初期化 CORBA::Long x = 10; a1 <<= x; // 左シフト代入演算子で、_tcに_tc_longを // _valueに値10を、リリースフラグにCORBA_TRUEを設定 a2 = a1; // 代入演算子で、a1のデータ(_tc,_value)の // 値をa2に複写し、リリースフラグにCORBA_TRUEを設定 // 代入演算子の処理内容 Any & Any::operator=( const Any &r ) { if( _release && _value ) delete value; // リリースフラグがCORBA_TRUEなら // 既存データを削除 TypeCode::_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に値42を、リリースフラグをCORBA_TRUEに設定 // 左シフト代入演算子の処理内容 void CORBA::Any::operator<<=( Long v ) { CORBA::release( _tc ); _tc = .... ( _tc_longを設定する処理) if( _release && _value ) delete _value; // リリースフラグが設定されている場合には_valueを削除 _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_FALSEを設定 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をチェックしなければなりません。
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関数は、パラメタで指定した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); // 以下の関数が呼ばれます。 // 代入演算子 Any::Any::replace( TypeCode_ptr tc, void *value, Boolean release = CORBA_FALSE) { _tc = ... // _tc_longを設定する処理 _value = value; _release = release; }
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関数は、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;
目次
索引
![]() ![]() |