![]() |
![]() |
|
|
バッファの割り当ておよび初期化を行う関数
ここでは、スタンドアロンの FML プログラムをコーディングするための関数を説明します。BEA Tuxedo の ATMI 関数を使用している場合に、メッセージ・バッファを割り当てたり、割り当てを解除するには、Falloc、Falloc32(3fml)、Frealloc、Frealloc32(3fml)、Ffree、Ffree32(3fml) などの FML 関数の代わりに、tpalloc(3c)、tprealloc(3c)、tpfree(3c) などの ATMI 関数を呼び出さなければなりません。
大半の FML 関数では、引数としてフィールド化バッファに対するポインタが必要です。このようなポインタを宣言するには、次の例のように、typedef 宣言をした FBFR を使用できます。
FBFR *fbfr;
この節では、変数 fbfr をフィールド化バッファに対するポインタとして使用します。フィールド化バッファ自体は宣言できません。宣言できるのは、フィールド化バッファに対するポインタだけです。
サーバは、FML バッファを含む要求を受け取ると、受け取った FML バッファと埋め込み型の VIEW または FLD_PTR フィールドが参照するバッファに対して領域を割り当てます。新しい FML バッファに対するポインタが、ユーザ記述コードに渡されます。サーバの処理が終了したら、メッセージ受信時に割り当てたバッファはすべて破棄しなければなりません。BEA Tuxedo システムによって FML バッファとすべての補助バッファが調べられ、参照が見つかったバッファはすべて削除されます。サーバ・コードをコーディングする場合は、以下の状況を認識しておく必要があります。
この節では、フィールド化バッファの領域を確保するための関数について説明します。まず、指定されたバッファがフィールド化バッファであるかどうかを判別するための関数を説明します。
Fielded
Fielded (または Fielded32) を使用すると、指定されたバッファがフィールド化されているかどうかをテストできます。
int
Fielded(FBFR *fbfr)
Fielded32 は 32 ビットの FML と共に使用します。
Fielded を使用すると、バッファがフィールド化されている場合は true (1) が返されます。バッファがフィールド化されていない場合は false (0) が返されます。この場合、Ferror は設定されません。
詳細については、『BEA Tuxedo FML リファレンス』の「Fielded、Fielded32(3fml)」を参照してください。
Fneeded
フィールド化バッファに割り当てるメモリ領域のサイズは、フィールド化バッファに指定できるフィールドの最大数と、すべてのフィールド値に必要な領域の合計サイズによって異なります。Fneeded を使用すると、フィールド化バッファに必要な領域 (バイト単位) を判別できます。この関数には引数として、フィールド数とすべてのフィールド値に必要な領域 (バイト単位) を指定します。
long
Fneeded(FLDOCC F, FLDLEN V)
以下はパラメータの説明です。
フィールド値に必要な領域は、各フィールド値が標準的な構造で格納された場合の領域を見積もることにより、算出できます。たとえば、long 型の値が long 型として格納されると、4 バイトの領域が必要です。可変長フィールドの場合は、フィールドに必要な領域の平均値を見積もります。Fneeded で算出される領域には、フィールドごとの固定オーバーヘッドが含まれます。つまり、フィールド値に必要な領域には、オーバーヘッド分が加算されます。
Fneeded を使用して必要な領域を見積もったら、malloc(3) を使用して必要なバイト数を割り当て、割り当てたメモリ領域に対するポインタを設定できます。たとえば、次のコードでは、フィールド化バッファに対し、25 個のフィールドと 300 バイトの値を格納できるだけの領域を割り当てています。
#define NF 25
#define NV 300
extern char *malloc;
. . .
if((fbfr = (FBFR *)malloc(Fneeded(NF, NV))) == NULL)
F_error("pgm_name"); /* バッファを割り当てる領域がない */
ただし、このコードで割り当てられたメモリ領域は、まだフィールド化バッファではありません。この領域は、Finit を使用して初期化する必要があります。
詳細については、『BEA Tuxedo FML リファレンス』の「Fneeded、Fneeded32(3fml)」を参照してください。
Fvneeded
Fvneeded 関数を使用すると、VIEW バッファに必要な領域 (バイト単位) を判別できます。この関数には、引数として VIEW の名前に対するポインタを指定します。
long
Fvneeded(char *subtype)
Fvneeded 関数は、VIEW のサイズをバイト数で返します。
詳細については、『BEA Tuxedo FML リファレンス』の「Fvneeded、Fvneeded32(3fml)」を参照してください。
Finit
Finit は、割り当てられたメモリ領域をフィールド化バッファとして初期化します。
int
Finit(FBFR *fbfr, FLDLEN buflen)
以下はパラメータの説明です。
Fneeded の例で割り当てたメモリ領域を初期化するために Finit を呼び出す場合は、以下の形式を使用します。
Finit(fbfr, Fneeded(NF, NV));
この呼び出しの結果、fbfr は、初期化された空のフィールド化バッファを指します。Fneeded (NF, NV) によって割り当てられた最大バイト数から、fml.h で定義された F_OVHD 分を差し引いたバイト数を、バッファのフィールド領域として使用できます。
注記 ただし、malloc(3) (前の節を参照) への呼び出しと Finit への呼び出しでは、同じ値を使用する必要があります。
詳細については、『BEA Tuxedo FML リファレンス』の「Finit、Finit32(3fml)」を参照してください。
Falloc
Fneeded、malloc(3)、および Finit に対する呼び出しは、Falloc に対する 1 回の呼び出しで置き換えることができます。この関数を使用すると、必要な領域を割り当て、バッファを初期化できます。
FBFR *
Falloc(FLDOCC F, FLDLEN V)
以下はパラメータの説明です。
前の 3 つの節で説明した、Fneeded、malloc()、および Finit と同じ機能を実行する Falloc への呼び出しは、次のようにコーディングします。
extern FBFR *Falloc;
. . .
if((fbfr = Falloc(NF, NV)) == NULL)
F_error("pgm_name"); /* バッファを割り当てることができなかった */
Falloc (または、Fneeded、malloc(3) および Finit) によって割り当てられた領域を解放するには、Ffree を使用します。『BEA Tuxedo FML リファレンス』の「Ffree、Ffree32(3fml)」を参照してください。
詳細については、『BEA Tuxedo FML リファレンス』の「Falloc、Falloc32(3fml)」を参照してください。
Ffree
Ffree は、フィールド化バッファとして割り当てられたメモリ領域を解放します。Ffree32 は、FLD_PTR フィールドのポインタによって参照されるメモリ領域を解放しません。
int
Ffree(FBFR *fbfr)
fbfr は、フィールド化バッファに対するポインタです。次の例を参照してください。
#include <fml.h>
. . .
if(Ffree(fbfr) < 0)
F_error("pgm_name"); /* フィールド化バッファではない */
free(3) より Ffree の使用をお勧めします。free(3) ではフィールド化バッファを無効にできませんが、Ffree を使用するとフィールド化バッファを無効にできます。フィールド化バッファの無効化が必要なのは、malloc(3) が解放されたメモリをクリアせずに再利用するためです。free(3) を使用すると、malloc が無効化されていないフィールド化バッファを返す可能性があります。
フィールド化バッファの領域を直接確保することもできます。フィールド化バッファは、short 型境界に調整させて開始する必要があります。バッファには、少なくとも F_OVHD 分のバイト (fml.h で定義) を割り当てる必要があります。割り当てないと、Finit からエラーが返されます。
以下のコードは、前の節の例と似ていますが、Fneeded はマクロではないため、静的バッファのサイズ指定には使用できません。
/* 最初の行でバッファを調整している */
static short buffer[500/sizeof(short)];
FBFR *fbfr=(FBFR *)buffer;
. . .
Finit(fbfr, 500);
以下のようなコードは入力しないでください。
FBFR badfbfr;
. . .
Finit(&badfbfr, Fneeded(NF, NV));
このコードは間違いです。FBFR の構造体がユーザのヘッダ・ファイルで定義されていません。したがって、コンパイル時にエラーが発生します。
詳細については、『BEA Tuxedo FML リファレンス』の「Ffree、Ffree32(3fml)」を参照してください。
Fsizeof
Fsizeof は、バイト単位でフィールド化バッファのサイズを返します。
long
Fsizeof(FBFR *fbfr)
fbfr は、フィールド化バッファに対するポインタです。たとえば、次のコードでは、Fsizeof は、フィールド化バッファの当初の割り当て時に Fneeded が返した数と同じ数を返します。
long bytes;
. . .
bytes = Fsizeof(fbfr);
詳細については、『BEA Tuxedo FML リファレンス』の「Fsizeof、Fsizeof32(3fml)」を参照してください。
Funused
Funused を使用すると、フィールド化バッファの領域のうち、追加データを格納するために使用できる領域を判別できます。
long
Funused(FBFR *fbfr)
fbfr は、フィールド化バッファに対するポインタです。次の例を参照してください。
long unused;
. . .
unused = Funused(fbfr);
Funused は、空き領域のバイト数のみを示し、バッファ内での空き領域の位置は示しません。
詳細については、『BEA Tuxedo FML リファレンス』の「Funused、Funused32(3fml)」を参照してください。
Fused
Fused を使用すると、フィールド化バッファ内でデータおよびオーバーヘッド用に使用されている領域を判別できます。
long
Fused(FBFR *fbfr)
fbfr は、フィールド化バッファに対するポインタです。次の例を参照してください。
long used;
. . .
used = Fused(fbfr);
Fused は、使用済み領域のバイト数のみを示し、バッファ内での位置は示しません。
詳細については、『BEA Tuxedo FML リファレンス』の「Fused、Fused32(3fml)」を参照してください。
Frealloc
この関数を使用すると、Falloc を呼び出して既に領域を割り当てたバッファのサイズを変更できます。
tpalloc(3c) で領域を割り当てた場合は、tprealloc(3c) を呼び出して領域を再び割り当てます。バッファのサイズ変更機能は、新しいフィールド値を追加したために空き領域が不足した場合などに役立ちます。このような場合は、単に Frealloc を呼び出すだけでバッファのサイズを増やすことができます。また、Frealloc を呼び出してバッファのサイズを小さくすることもできます。
FBFR *
Frealloc(FBFR *fbfr, FLDOCC nf, FLDLEN nv)
以下はパラメータの説明です。
次の例を参照してください。
FBFR *newfbfr;
. . .
if((newfbfr = Frealloc(fbfr, NF+5, NV+300)) == NULL)
F_error("pgm_name"); /* 領域を再割り当てできなかった */
else
fbfr = newfbfr; /* 新しいポインタを設定する */
この例では、アプリケーション側で、既に割り当てられたフィールド数と値の領域のバイト数を認識している必要があります。Frealloc の引数 (および対応する realloc(3) ) は絶対値であり、増分値ではありません。領域の割り当てを複数回行う必要がある場合、このコード例は正しく動作しません。
以下の例では、割り当てられた領域を増分する別の方法を示します。
/* バッファがなくなった時にサイズを増やす */
#define INCR 400
FBFR *newfbfr;
. . .
if((newfbfr = Frealloc(fbfr, 0, Fsizeof(fbfr)+INCR)) == NULL)
F_error("pgm_name"); /* 領域を再割り当てできなかった */
else
fbfr = newfbfr; /* 新しいポインタを設定する */
この例では、バッファが最後に初期化されたときのフィールド数や値の領域のサイズを知っておく必要はありません。したがって、サイズを増やす最も簡単な方法は、現在のサイズに増分値を加えたサイズを値の領域として使用することです。上の例は、必要に応じて何回でも実行することができます。過去の実行内容や値を覚えておく必要はありません。Frealloc を呼び出した後で Finit を呼び出す必要はありません。
Frealloc に対する呼び出しで要求した追加の領域が古いバッファと隣接している場合は、上の例の newfbfr と fbfr は同一になります。ただし、プログラムが正しく実行されるようにするため、newfbfr を宣言しておき、新しい値または NULL 値が返されるのを防ぐ必要があります。Frealloc が失敗した場合、fbfr は再使用しないでください。
注記 バッファ・サイズは、バッファ内で現在使用中のバイト数までしか縮小できません。
詳細については、『BEA Tuxedo FML リファレンス』の「Frealloc、Frealloc32(3fml)」を参照してください。
![]() |
![]() |
![]() |
|
Copyright © 2001 BEA Systems, Inc. All rights reserved.
|