BEA Logo BEA Tuxedo Release 8.0

  BEA ホーム  |  イベント  |  ソリューション  |  パートナ  |  製品  |  サービス  |  ダウンロード  |  ディベロッパ・センタ  |  WebSUPPORT

 

   Tuxedo ホーム   |   C 言語を使用した BEA Tuxedo アプリケーションのプログラミング   |   先頭へ   |   前へ   |   次へ   |   目次

 


バッファのカスタマイズ

BEA Tuxedo システムで提供されるバッファ・タイプでは、アプリケーションのニーズが満たされない場合があります。たとえば、アプリケーションがフラットではないデータ構造体、つまり SQL データベースの問い合わせのための解析ツリーなど、ほかのデータ構造体へのポインタを持つデータ構造を扱う場合があります。アプリケーション固有の要件に対応するために、BEA Tuxedo システムではカスタム・バッファがサポートされています。

バッファをカスタマイズするには、次の特性を理解しておきます。

カスタム・バッファ・タイプの特性

特性

説明

バッファ・タイプ

バッファ・タイプの名前。8 文字以内の文字列で指定します。

バッファ・サブタイプ

バッファ・サブタイプの名前。16 文字以内の文字列で指定します。サブタイプは、特定のタイプのバッファに必要となる処理の違いを示すために使用されます。サブタイプ値としてワイルドカード文字 (*) を指定すると、同じ汎用ルーチンを使用して、指定されたタイプのすべてのバッファが処理されます。サブタイプが定義されているバッファは、リスト内でワイルドカードより前に置く必要があります。置かないと、処理が正常に行われません。

デフォルト・サイズ

対応するバッファ・タイプが割り当てまたは再割り当てされるときの最大サイズ。バッファ・タイプにゼロより大きい適切な値が設定されている場合、バッファを割り当てや再割り当てする際に、バッファ・サイズにゼロを指定できます。

次の表は、各バッファ・タイプに指定する必要があるルーチンを示しています。特定のルーチンが必要ない場合は、NULL ポインタを指定します。必要に応じて、BEA Tuxedo システムでデフォルトの処理が行われます。

カスタム・バッファ・タイプのルーチン

ルーチン

説明

バッファの初期化

新しく割り当てられた型付きバッファを初期化します。

バッファの再初期化

型付きバッファを再初期化します。このルーチンは、バッファが新しいサイズで再割り当てされたときに呼び出されます。

バッファの非初期化

型付きバッファを非初期化します。このルーチンは、型付きバッファが解放される直前に呼び出されます。

バッファの送信前処理

型付きバッファを送るための前処理を行います。このルーチンは、メッセージとして型付きバッファを別のクライアントやサーバに送信する前に呼び出されます。転送されるデータの長さが返されます。

バッファの送信後処理

型付きバッファを元の状態に戻します。このルーチンは、メッセージの送信後に呼び出されます。

バッファの受信後処理

アプリケーションで受信された型付きバッファを準備します。アプリケーション・データの長さが返されます。

符号化/複合化

バッファ・タイプで必要なすべての符号化と復号化を行います。入力バッファと出力バッファ、およびその長さと共に、符号化や復号化の要求がルーチンに渡されます。符号化に使用される形式はアプリケーションで決定され、ほかのルーチンと同じように、バッファ・タイプによって異なる場合があります。

ルーティング

ルーティング情報を指定します。このルーチンは、型付きバッファ、バッファのデータ長、管理者が設定した論理的なルーティング名、およびターゲット・サービスを指定して呼び出されます。この情報に基づいて、アプリケーションでメッセージの送信先サーバ・グループが選択されるか、またはメッセージが不要であることが決定されます。

フィルタ処理

フィルタ情報を指定します。このルーチンは、型付きバッファに対する式の評価するときに呼び出され、合致したかどうかを返します。型付きバッファが VIEW または FML の場合、FML 論理式が使用されます。イベント・ブローカは、このルーチンを使用してイベントが合致しているかどうかを評価します。

フォーマット処理

型付きバッファの印字可能な文字列を指定します。

独自のバッファ・タイプの定義

領域の割り当てと解放、メッセージの送受信など、バッファを操作するコードを記述するのはアプリケーション・プログラマです。デフォルトのバッファ・タイプではアプリケーションのニーズを満たすことができない場合、ほかのバッファ・タイプを定義し、新しいルーチンを記述してバッファ・タイプ・スイッチに組み込むことができます。

ほかのバッファ・タイプを定義するには、次の手順に従います。

  1. 必要なスイッチ・エレメント・ルーチンのコードを記述します。

  2. tm_typesw に、新しいタイプとバッファ管理モジュールの名前を追加します。

  3. 新しい共用オブジェクトまたは DLL をビルドします。共用オブジェクトまたは DLL には、更新されたバッファ・タイプ・スイッチとそれに対応する関数が含ま れていなければなりません。

  4. 新しい共用オブジェクトまたは DLL をインストールして、すべてのサーバ、クラ イアント、および BEA Tuxedo システムで提供される実行可能ファイルが実行時 に動的にロードされるようにします。

静的ライブラリが使用されるアプリケーションで、カスタム・バッファ・タイプ・スイッチを使う場合は、カスタム・サーバをビルドして、新しいタイプ・スイッチにリンクする必要があります。詳細については、buildwsh (1)、TMQUEUE (5)、TMQFORWARD (5) を参照してください。

ここでは、前述の手順に従って、共用オブジェクトまたは DLL 環境で新しいバッファ・タイプを定義します。その前に、BEA Tuxedo システム・ソフトウェアに提供されているバッファ・スイッチを参照してみます。次のコード例は、システムに提供されているスイッチです。

デフォルトのバッファ・タイプ・スイッチ

#include <stdio.h>
#include <tmtypes.h>

/* バッファ・タイプ・スイッチの初期化 */
static struct tmtype_sw_t tm_typesw[] = {
{
"CARRAY", /* type */
"", /* subtype */
0 /* dfltsize */
},
{
"STRING", /* type */
"", /* subtype */
512, /* dfltsize */
NULL, /* initbuf */
NULL, /* reinitbuf */
NULL, /* uninitbuf */
_strpresend, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
_strencdec, /* encdec */
NULL, /* route */
NULL, /* filter */
NULL /* format */
},
{
"FML", /* type */
"", /* subtype */
1024, /* dfltsize */
_finit, /* initbuf */
_freinit, /* reinitbuf */
_funinit, /* uninitbuf */
_fpresend, /* presend */
_fpostsend, /* postsend */
_fpostrecv, /* postrecv */
_fencdec, /* encdec */
_froute, /* route */
_ffilter, /* filter */
_fformat /* format */
},
{
"FML32", /* type */
"", /* subtype */
1024, /* dfltsize */
_finit32, /* initbuf */
_freinit32, /* reinitbuf */
_funinit32, /* uninitbuf */
_fpresend32, /* presend */
_fpostsend32, /* postsend */
_fpostrecv32, /* postrecv */
_fencdec32, /* encdec */
_froute32, /* route */
_ffilter32, /* filter */
_fformat32 /* format */
},
{
"VIEW", /* type */
"*", /* subtype */
1024, /* dfltsize */
_vinit, /* initbuf */
_vreinit, /* reinitbuf */
NULL, /* uninitbuf */
_vpresend, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
_vencdec, /* encdec */
_vroute, /* route */
_vfilter, /* filter */
_vformat /* format */
},
{
"VIEW32", /* type */
"*" /* subtype */
1024, /* dfltsize */
_vinit32, /* initbuf */
_vreinit32, /* reinitbuf */
NULL, /* uninitbuf */
_vpresend32, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
_vencdec32, /* encdec */
_vroute32, /* route */
_vfilter32, /* filter */
_vformat32 /* format */
},
{
"X_OCTET", /* type */
"", /* subtype */
0, /* dfltsize */
},
{
"'X','_','C','_','T','Y','P','E'", /* type */
"*", /* subtype */
1024, /* dfltsize */
_vinit, /* initbuf */
_vreinit, /* reinitbuf */
NULL, /* uninitbuf */
_vpresend, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
_vencdec, /* encdec */
_vroute, /* route */
_vfilter, /* filter */
_vformat /* format */
},
{
"'X','_','C','O','M','M','O','N'", /* type */
"*", /* subtype */
1024, /* dfltsize */
_vinit, /* initbuf */
_vreinit, /* reinitbuf */
NULL, /* uninitbuf */
_vpresend, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
_vencdec, /* encdec */
_vroute, /* route */
_vfilter, /* filter */
_vformat /* format */
},
{
"XML", /* type */
"*", /* subtype */
0, /* dfltsize */
NULL, /* _xinit - 使用不能 */
NULL, /* _xreinit - 使用不能 */
NULL, /* _xuninit - 使用不能 */
NULL, /* _xpresend - 使用不能 */
NULL, /* _xpostsend - 使用不能 */
NULL, /* _xpostrecv - 使用不能 */
NULL, /* _xencdec - 使用不能 */
_xroute, /* _xroute */
NULL, /* filter - 使用不能 */
NULL /* format - 使用不能 */
},
{
""
}
};

この例をよく理解できるように、次の例に示すバッファ・タイプ構造体の宣言を参照してください。

バッファ・タイプ構造体

/* 以下の定義は、$TUXDIR/tuxedo/include/tmtypes.h にあります。 */
#define TMTYPELEN        8
#define TMSTYPELEN 16

struct tmtype_sw_t {
char type[TMTYPELEN]; /* バッファのタイプ */
char subtype[TMSTYPELEN]; /* バッファのサブタイプ */
long dfltsize; /* バッファのデフォルト・サイズ */
/* バッファ初期化関数へのポインタ */
int (_TMDLLENTRY *initbuf) _((char _TM_FAR *, long));
/* バッファ再初期化関数へのポインタ */
int (_TMDLLENTRY *reinitbuf) _((char _TM_FAR *, long));
/* バッファ非初期化関数へのポインタ */
int (_TMDLLENTRY *uninitbuf) _((char _TM_FAR *, long));
/* バッファ送信前処理関数へのポインタ */
long (_TMDLLENTRY *presend) _((char _TM_FAR *, long, long));
/* バッファ送信後処理関数へのポインタ */
void (_TMDLLENTRY *postsend) _((char _TM_FAR *, long, long));
/* バッファ受信後処理関数へのポインタ*/
long (_TMDLLENTRY *postrecv) _((char _TM_FAR *, long, long));
/* 符号化/復号化関数へのポインタ */
long (_TMDLLENTRY *encdec) _((int, char _TM_FAR *, long,
char _TM_FAR *, long));
/* ルーティング関数へのポインタ */
int (_TMDLLENTRY *route) _((char _TM_FAR *, char _TM_FAR *,
char _TM_FAR *, long, char _TM_FAR *));
/* バッファ・フィルタ処理関数へのポインタ */
int (_TMDLLENTRY *filter) _((char _TM_FAR *, long, char _TM_FAR *,
long));
/* バッファ・フォーマット処理関数へのポインタ */
int (_TMDLLENTRY *format) _((char _TM_FAR *, long, char _TM_FAR *,
char _TM_FAR *, long));
/*この領域は将来の拡張のために予約されています。 */
void (_TMDLLENTRY *reserved[10]) _((void));
};

前述のデフォルト・バッファ・タイプ・スイッチの例は、バッファ・タイプ・スイッチの初期化を示しています。9 つのデフォルト・バッファ・タイプの後に、サブタイプの名前を指定するフィールドがあります。VIEW (X_C_TYPEX_COMMON) 型を除き、サブタイプは NULL です。VIEW のサブタイプは "*'' として指定されています。これは、デフォルトのVIEW 型のサブタイプに制約がないことを示します。つまり、VIEW 型のすべてのサブタイプは同じ方法で処理されます。

次のフィールドには、バッファのデフォルト (最小) サイズが指定されています。CARRAY (X_OCTET) 型の場合、このフィールドに 0 が指定されています。これは、CARRAY 型バッファを使用するルーチンでは、CARRAY 型に必要な領域を tpalloc() で割り当てなければならないことを示します。

それ以外のバッファ・タイプの場合、tpalloc() が呼び出されて、dfltsize フィールドに指定されている領域が BEA Tuxedo システムによって割り当てられます。ただし、tpalloc() のサイズを示す引数にこれより大きな値が設定されていない場合に限ります。

バッファ・タイプ・スイッチのエントリで、残りの 8 つのフィールドには、スイッチ・エレメント・ルーチンの名前が指定されています。これらのルーチンの詳細については、BEA Tuxedo C リファレンス の buffer(3c) を参照してください。ルーチン名からそのルーチンの処理内容がわかります。たとえば、FML 型の _fpresend は、送信前にバッファを操作するルーチンを指すポインタです。送信前処理が必要ない場合は、NULL ポインタを指定します。NULL は、特に処理が必要ないことを示し、その結果デフォルトの処理が行われます。詳細については、buffer(3c) を参照してください。

スイッチの最後に NULL エントリがあることに注目してください。変更時には、配列の終わりに必ず NULL エントリを置いてください。

スイッチ・エレメント・ルーチンのコーディング

アプリケーションで新しいバッファ・タイプを定義するのは、特別な処理を行うためです。たとえば、アプリケーションで、次のプロセスにバッファを送信する前に、データ圧縮を何度か行うとします。このようなアプリケーションでは、送信前処理ルーチンを記述します。次のコード例は、送信前処理ルーチンの宣言を示しています。

送信前処理スイッチ・エレメントのセマンティクス

long
presend(ptr, dlen, mdlen)
char *ptr;

long dlen, mdlen;

送信前処理ルーチンで行うデータ圧縮は、アプリケーションのシステム・プログラマが行います。

ルーチンの処理が正常に終了した場合、同じバッファ内にある圧縮後の送信データの長さが返されます。処理が失敗した場合は、-1 が返されます。

プログラマが記述した送信前処理ルーチンには、C コンパイラが使用できる任意の識別子を付けることができます。たとえば、_mypresend という名前を付けます。

_mypresend 圧縮ルーチンを使用する場合、受信側にはそのデータの圧縮を解除する _mypostrecv ルーチンが必要です。BEA Tuxedo C リファレンス の buffer(3c) に示すテンプレートを使用してください。

tm_typesw への新しいバッファ・タイプの追加

新しいスイッチ・エレメント・ルーチンを記述し、そのコンパイルに成功したら、そのバッファ・タイプ・スイッチに新しいバッファ・タイプを追加する必要があります。その場合、$TUXDIR/lib/tmtypesw.c をコピーします。これはデフォルトのバッファ・タイプ・スイッチのソース・コードです。コピーしたファイル名に、mytypesw.c など、拡張子として .c を付けます。コピーしたファイルに新しいタイプを追加します。タイプ名は 8 文字以内で指定します。サブタイプには、NULL ("") または 16 文字以内の文字列を指定できます。新しいスイッチ・エレメント・ルーチンの名前は、extern 宣言も含めて適切な場所に入力します。次の例は、バッファ・スイッチに新しいタイプを追加しています。

新しいタイプのバッファ・スイッチへの追加

#include <stdio.h>
#include <tmtypes.h>

/* カスタマイズしたバッファ・タイプ・スイッチ */

static struct tmtype_sw_t tm_typesw[] = {
{
"SOUND", /* type */
"", /* subtype */
50000, /* dfltsize */
snd_init, /* initbuf */
snd_init, /* reinitbuf */
NULL, /* uninitbuf */

snd_cmprs, /* presend */
snd_uncmprs, /* postsend */
snd_uncmprs /* postrecv */
},
{
"FML", /* type */
"", /* subtype */
1024, /* dfltsize */
_finit, /* initbuf */
_freinit, /* reinitbuf */
_funinit, /* uninitbuf */
_fpresend, /* presend */
_fpostsend, /* postsend */
_fpostrecv, /* postrecv */
_fencdec, /* encdec */
_froute, /* route */
_ffilter, /* filter */
_fformat /* format */
},
{
""
}
};

この例では、SOUND という新しいタイプを追加しています。また、VIEWX_OCTETX_COMMON、および X_C_TYPE のエントリを削除して、デフォルト・スイッチで不要なエントリを削除できることを示しています。配列の最後に NULL があることに注目してください。

新しいバッファ・タイプを定義する別の方法は、既存のタイプを再定義することです。バッファ・タイプ MYTYPE に定義したデータ圧縮が文字列に対して実行されたとします。その場合、STRING 型の 2 つの _dfltblen の代わりに、新しいスイッチ・エレメント・ルーチン _mypresend_mypostrecv を使用できます。

新しい tm_typesw のコンパイルとリンク

インストールを簡単に行うには、バッファ・タイプ・スイッチを共用オブジェクトに格納します。

注記 一部のプラットフォームでは、「共用オブジェクト」ではなく「共用ライブラリ」という言葉が使用されています。Windows 2000 プラットフォームでは、「共用オブジェクト」ではなく「ダイナミック・リンク・ライブラリ」と呼ばれています。この 3 つの用語が示す機能は同じなので、ここでは「共用オブジェクト」を使用します。

ここでは、アプリケーション内のすべての BEA Tuxedo プロセスに、変更後のバッファ・タイプ・スイッチを認識させる方法について説明します。これらのプロセスには、BEA Tuxedo システムで提供されるサーバとユーティリティのほかに、アプリケーション・サーバおよびアプリケーション・クライアントも含まれています。

  1. $TUXDIR/lib/tmtypesw.c をコピーして変更します。「tm_typesw への新しい バッファ・タイプの追加」を参照してください。関数を追加する場合は、それら の関数を tmtypesw.c に記述するか、別の C ソース・ファイルに記述します。

  2. 共用オブジェクトに必要なフラグを設定し、tmtypesw.c をコンパイルします。

  3. すべてのオブジェクト・ファイルをリンクして、共用オブジェクトを生成しま す。

  4. libbuft.so.71 をカレント・ディレクトリから別のディレクトリにコピーしま す。コピー先のディレクトリとしては、アプリケーションが libbuft.so.71 を 認識でき、BEA Tuxedo システムで提供されるデフォルトの共用オブジェクトより 先に libbuft.so.71 が処理されるディレクトリを選択します。$APPDIR または $TUXDIR/lib ディレクトリ、または $TUXDIR/bin (Windows 2000 の場合) のい ずれかを使用することをお勧めします。

オペレーティング・システムの規則に従うために、プラットフォームが異なる場合は、バッファ・タイプ・スイッチ共用オブジェクトには異なる名前が使用されます。

バッファ・タイプ・スイッチ共用オブジェクトの OS 別の名前

プラットフォームの種類

バッファ・タイプ・スイッチ共用オブジェクトの名前

UNIX システム (大部分は SVR4)

libbuft.so.71

HP-UX

libbuft.sl

Sun OS

libbuft.so.71

Windows (16 ビット)

wbuft.dll

Windows (32 ビット)

wbuft32.dll

OS/2 (16 ビット)

obuft.dll

OS/2 (32 ビット)

obuft.dll

共用オブジェクト・ライブラリのビルド方法については、お使いのプラットフォームのソフトウェア開発マニュアルを参照してください。

別の方法として、すべてのクライアント・プロセスとサーバ・プロセスで新しいバッファ・タイプ・スイッチを静的にリンクすることもできます。ただし、この方法ではエラーが発生しやすくなり、効率も共用オブジェクト・ライブラリをビルドするより劣ります。

16 ビット Windows プラットフォーム用の新しい tm_typesw のコンパイルとリンク

「新しい tm_typesw のコンパイルとリンク」で説明したように、Windows プラットフォーム上で tmtypesw.c を変更した場合、次のコード例に示すコマンドを使用して、変更後のバッファ・タイプ・スイッチをアプリケーションから使用できるようにします。

Microsoft Visual C++ のコード例

CL -AL -I..\e\|sysinclu -I..\e\|include -Aw -G2swx -Zp -D_TM_WIN
-D_TMDLL -Od -c TMTYPESW.C
LINK /CO /ALIGN:16 TMTYPESW.OBJ, WBUFT.DLL, NUL, WTUXWS /SE:250 /NOD
/NOE LIBW LDLLCEW, WBUFT.DEF
RC /30 /T /K WBUFT.DLL

データ変換

コンフィグレーション・ファイルの MACHINES セクションにある TYPE パラメータは、データ表現と使用するコンパイラが同じであるマシンをグループ化して、TYPE が異なるマシン間でやり取りされるメッセージのデータが変換されるようにします。デフォルトのバッファ・タイプの場合、異なるマシン間でのデータ変換はユーザ、管理者、プログラマに対して透過的です。

アプリケーションで新しいバッファ・タイプを定義して、データ表現スキーマが異なるマシン間でメッセージを交換する場合、新しい符号化/復号化ルーチンを記述して、バッファ・タイプ・スイッチに組み込む必要があります。独自のデータ変換ルーチンを記述する場合は、次のガイドラインに従ってください。

符号化/復号化ルーチンが呼び出されるのは、データをやり取りする 2 つのマシンの TYPE が異なることが BEA Tuxedo システムによって検出された場合だけです。

 

先頭へ戻る 前のトピックへ 次のトピックへ