1 つ以上のユーザー作成ヒープを作成することによって、 活動化グループ内の一部のプログラムおよびプロシージャーで使用される動的記憶域を分離することができます。 ユーザー作成ヒープの作り方については、「ILE 概念」を参照してください。
次の例は、ILE RPG プロシージャーからユーザー作成ヒープを使用して、実行時配列用の動的記憶域を管理する方法を示したものです。 この例では、モジュール DYNARRAY 内のプロシージャーが、 実際にバインドされていないパック配列に記憶域を動的に割り振ります。 このモジュール内のプロシージャーは、この配列で以下の処置を実行します。
DYNARRAY は、REALLOC 命令コードだけでなく、CEECRHP (ヒープ作成)、CEEGTST (記憶域取得)、および CEEDSHP (ヒープ廃棄) という 3 つの ILE バインド可能記憶域 API を使用してこれらの処置を行います。 記憶域管理バインド可能 API に特有の情報は、Web サイト http://www.ibm.com/eserver/iseries/infocenter で iSeries Information Center の中の『プログラミン グ』カテゴリーの『CL および API』の節を参 照してください。
図 55 では、DYNARRAY 内のプロシージャーのプロトタイプを含む、/COPY ファイル DYNARRI を示します。 この /COPY ファイルは、DYNARRAY にプロシージャーを呼び出す その他のモジュールだけでなく、DYNARRAY モジュールによって使用されます。
DYNARRAY は、(15,0) パック 10 進数配列で使用されるように定義されています。 これは、単に DYNA_TYPE の定義を文字フィールドに変更することによって、 文字配列の処理を容易に変換することができます。
*================================================================= * DYNARRAY : (実際には) バインドされていない実行時パック (15,0) * 配列の処理。DYNARRAY モジュールには、配列を割り振り、 * 配列値を戻すか設定し、配列を割り振り解除する * プロシージャーが含まれています。 *================================================================= D DYNA_TYPE S 15P 0 D DYNA_INIT PR D DYNA_TERM PR D DYNA_SET PR D Element VALUE LIKE(DYNA_TYPE) D Index 5I 0 VALUE D DYNA_GET PR LIKE(DYNA_TYPE) D Index 5I 0 VALUE
図 56 は、制御仕様書と定義仕様書を含むモジュール DYNARRAY の最初の部分を示します。
*================================================================= * DYNARRAY : (実際には) バインドされていない実行時パック (15,0) * 配列の処理。このモジュールには、配列を割り振り、 * 配列値を戻すか設定し、配列を割り振り解除する * プロシージャーが含まれています。 *================================================================= H NOMAIN *----------------------------------------------------------------- * このモジュール内のプロシージャー用のプロトタイプ *----------------------------------------------------------------- /COPY DYNARRI *----------------------------------------------------------------- * CEEGTST API (ヒープ記憶域取得) へのインターフェース * 1) HeapId = ヒープの ID。 * 2) Size = 割り振るバイト数 * 3) RetAddr= 割り振られた記憶域の戻りアドレス * 4) *OMIT = フィードバック・パラメーター。ここに *OMIT を指定 * することは、要求が満たされなかった時に API から * 例外を受け取ることを意味します。 * これを監視しているわけではないので、呼び出し * プロシージャーが例外を受け取ることになります。 *----------------------------------------------------------------- D CEEGTST PR D HeapId 10I 0 CONST D Size 10I 0 CONST D RetAddr * D Feedback 12A OPTIONS(*OMIT) *----------------------------------------------------------------- * CEECRHP API (ヒープ作成) へのインターフェース * 1) HeapId = ヒープの ID。 * 2) InitSize = ヒープの初期サイズ。 * 3) Incr = ヒープを拡大する必要がある場合に * 増分するバイト数。 * 4) AllocStrat = このヒープの場合の割り振り方法。値を * 0 に設定すると、システムが * 最適な方法を選択することができます。 * 5) *OMIT = フィードバック・パラメーター。ここに *OMIT を指定 * することは、要求が満たされなかった時に API から * 例外を受け取ることを意味します。 * これを監視しているわけではないので、呼び出し * プロシージャーが例外を受け取ることになります。 *----------------------------------------------------------------- D CEECRHP PR D HeapId 10I 0 D InitSize 10I 0 CONST D Incr 10I 0 CONST D AllocStrat 10I 0 CONST D Feedback 12A OPTIONS(*OMIT)
*----------------------------------------------------------------- * CEEDSHP API (ヒープ廃棄) へのインターフェース * 1) HeapId = ヒープの ID。 * 2) *OMIT = フィードバック・パラメーター。ここに *OMIT を指定 * することは、要求が満たされなかった時に API から * 例外を受け取ることを意味します。 * これを監視しているわけではないので、呼び出し * プロシージャーが例外を受け取ることになります。 *----------------------------------------------------------------- D CEEDSHP PR D HeapId 10I 0 D Feedback 12A OPTIONS(*OMIT) *----------------------------------------------------------------- * グローバル変数 *----------------------------------------------------------------- D HeapVars DS D HeapId 10I 0 D DynArr@ * *----------------------------------------------------------------- * 動的配列の定義。要素数を使用可能な最大数でコーディングしますが、 * この定義には実際には記憶域は宣言されないことに注意して * ください (これが BASED であるため)。 *----------------------------------------------------------------- D DynArr S DIM(32767) BASED(DynArr@) D LIKE(DYNA_TYPE) *----------------------------------------------------------------- * 動的配列の要素の現在数を、 * 常にグローバルに記録しておきます。 *----------------------------------------------------------------- D NumElems S 10I 0 INZ(0) *----------------------------------------------------------------- * 配列に割り振られる要素の初期数および * 後続の割り振りで配列に追加される * 要素の最小数。 *----------------------------------------------------------------- D INITALLOC C 100 D SUBSALLOC C 100
図 57 は DYNARRAY にあるサブプロシージャーを示したものです。
*================================================================= * DYNA_INIT: 配列を初期化します。 * * 機能: ヒープを作成し、実行時配列に記憶域の初期量を * 割り振ります。 *================================================================= P DYNA_INIT B EXPORT *----------------------------------------------------------------- * ローカル変数。 *----------------------------------------------------------------- D Size S 10I 0 * * 事前に定義された要素数で開始します。 * C Z-ADD INITALLOC NumElems * * 配列に必要なバイト数を決定します。 * C EVAL Size = NumElems * %SIZE(DynArr) * * ヒープの作成 * C CALLP CEECRHP(HeapId : Size : 0 : 0 : *OMIT) * * 記憶域を割り振り、配列の基底ポインターを、API から * 戻されたポインターに設定します。 * * ALLOC 命令コードがデフォルト・ヒープを使用するため、CEEGTST API を * 使用して別のヒープを指定する必要があることに注意してください。 * C CALLP CEEGTST(HeapId : Size : DynArr@ : *OMIT) * * 配列の記憶域の初期化 * C 1 DO NumElems I 5 0 C CLEAR DynArr(I) C ENDDO P DYNA_INIT E
*================================================================= * DYNA_TERM: 配列処理を終了させます。 * * 機能: ヒープを削除します。 *================================================================= P DYNA_TERM B EXPORT C CALLP CEEDSHP(HeapId : *OMIT) C RESET HeapVars P DYNA_TERM E
*================================================================= * DYNA_SET: 配列要素を設定します。 * * 機能: この要素に対して配列が十分な大きさであることを確認して、 * 要素を指定された値に設定します。 *================================================================= P DYNA_SET B EXPORT *----------------------------------------------------------------- * このプロシージャーの入力パラメーター。 *----------------------------------------------------------------- D DYNA_SET PI D Element VALUE LIKE(DYNA_TYPE) D Index 5I 0 VALUE *----------------------------------------------------------------- * ローカル変数。 *----------------------------------------------------------------- D Size S 10I 0 *----------------------------------------------------------------- * 配列への追加を選択した場合には、配列が十分に大きいかどうかが * 最初に検査され、十分でない場合にはそのサイズが増やされます。 * 要素を追加します。 *----------------------------------------------------------------- C Index IFGT NumElems C EXSR REALLOC C ENDIF C EVAL DynArr(Index) = Element *================================================================= * REALLOC: 記憶域再割り振りサブルーチン * * 機能: 動的配列のサイズを増やして、 * 新しい要素を初期化します。 *================================================================= C REALLOC BEGSR * * 元の要素の数を記憶 * C Z-ADD NumElems OldElems 5 0
* * 新しい要素の数を計算します。指標が配列内の現在の要素数に * 新しい割り振り数を加えたものより大きい場合には、その * 指標まで割り振り、そうでない場合には * 配列に新しい割り振り量を加算します。 * C IF Index > NumElems + SUBSALLOC C Z-ADD Index NumElems C ELSE C ADD SUBSALLOC NumElems C ENDIF * * 配列の新しいサイズを計算します * C EVAL Size = NumElems * %SIZE(DynArr) * * 記憶域を再割り振りします。新しい記憶域の値は、元の記憶域と * 同じです。 * C REALLOC Size DynArr@ * * 配列の新しい要素を初期化します。 * C 1 ADD OldElems I C I DO NumElems I 5 0 C CLEAR DynArr(I) C ENDDO C ENDSR P DYNA_SET E
*================================================================= * DYNA_GET: 配列要素を戻します。 * * 機能: 配列要素が配列のサイズ内である場合には、この要素の * 現在の値を戻します。そうでない場合には、 * デフォルト値を戻します。 *================================================================= P DYNA_GET B EXPORT *----------------------------------------------------------------- * このプロシージャーの入力パラメーター。 *----------------------------------------------------------------- D DYNA_GET PI LIKE(DYNA_TYPE) D Index 5I 0 VALUE *----------------------------------------------------------------- * ローカル変数。 *----------------------------------------------------------------- D Element S LIKE(DYNA_TYPE) INZ *----------------------------------------------------------------- * 要求した配列が現行サイズ内であれば、この要素の現行値を * 戻します。そうでない場合には、デフォルト (初期化) の値を * 使用することができます。 *----------------------------------------------------------------- C Index IFLE NumElems C EVAL Element = DynArr(Index) C ENDIF C RETURN Element P DYNA_GET E
このサブプロシージャーのロジックは次のとおりです。
要素を配列に追加する前に、プロシージャーは十分なヒープ記憶域があるかどうかを調べます。 十分でない場合には、命令コード REALLOC を使用して追加の記憶域を取得します。
モジュール DYNARRAY を作成するには、以下のとおりタイプしてください。
CRTRPGMOD MODULE(MYLIB/DYNARRAY) SRCFILE(MYLIB/QRPGLESRC)
このプロシージャーは、この後で CRTPGM または CRTSRVPGM を使用してその他の モジュールとバインドすることができます。
図 58 DYNARRAY 内のモジュールをテストする、別のモジュールを示します。
*================================================================= * DYNTEST: DYNARRAY モジュールのテスト・プログラム *================================================================= /COPY EXAMPLES,DYNARRI D X S LIKE(DYNA_TYPE) * 配列の初期化 C CALLP DYNA_INIT * 一部要素の設定 C CALLP DYNA_SET (25 : 3) C CALLP DYNA_SET (467252232 : 1) C CALLP DYNA_SET (-2311 : 750) * 一部要素の検索 C EVAL X = DYNA_GET (750) C '750' DSPLY X C EVAL X = DYNA_GET (8001) C '8001' DSPLY X C EVAL X = DYNA_GET (2) C '2' DSPLY X * 終結処理 C CALLP DYNA_TERM C SETON LR
(C) Copyright IBM Corporation 1992, 2006. All Rights Reserved.