C 言語を使用した Oracle Tuxedo アプリケーションのプログラミング

     前  次    新しいウィンドウで目次を開く     
ここから内容の開始

型付きバッファの管理

ここでは、以下の内容について説明します。

 


型付きバッファの概要

あるプロセスから別のプロセスにメッセージを送信する場合、メッセージ データ用のバッファを割り当てておく必要があります。Oracle Tuxedo システムのクライアントは、型付きバッファを使用してサーバにメッセージを送ります。型付きバッファとは、カテゴリ (タイプ) と、サブカテゴリ (サブタイプ) が定義されたメモリ領域です。サブカテゴリは必須ではありません。型付きバッファは、Oracle Tuxedo システムでサポートされる分散プログラミング環境の基本要素の 1 つです。

なぜ「型付き」レコードを使用するのでしょうか。分散環境では、アプリケーションが異機種システムにインストールされ、異なるプロトコルを使用して複数のネットワーク間で通信が行われます。バッファ タイプが異なると、初期化、メッセージの送受信、およびデータのエンコード/デコードにそれぞれ別のルーチンが必要になります。各バッファに特定のタイプが割り当てられていると、プログラマが介在しなくても、そのタイプに対応するルーチンを自動的に呼び出すことができます。

以下に示す表は、Oracle Tuxedo システムでサポートされる型付きバッファと、そのバッファが次の条件を満たしているかどうかを示しています。

ルーティング関数が必要な場合は、アプリケーション プログラマが用意します。

表 3-1 型付きバッファ
型付きバッファ
説明
自己記述型
サブタイプ
データ依存型
ルーティング
エンコード/デコード
CARRAY
未定義の文字配列。NULL 文字を含むことができます。Oracle Tuxedo システムでは配列のセマンティクスは解釈されないので、この型付きバッファは曖昧なデータを処理する場合に使用します。CARRAY は自己記述型ではないので、転送時には長さを指定する必要があります。システムではバイトは解釈されないので、マシン間のメッセージ送信ではエンコード/デコードはサポートされません。
該当せず
該当せず
該当せず
該当せず
FML (フィールド操作言語)
Oracle Tuxedo システム固有の自己記述型バッファ タイプ。このバッファでは、各データ フィールドに対応する識別子、オカレンス番号、場合によっては長さを示す値が格納されています。データ操作はすべて、ネイティブな C 言語の文ではなく FML 関数を使用して行われます。このため、処理に多少のオーバーヘッドが生じてでも、FML バッファを通じて、データの独立性と動作の柔軟性が確保されるようになっています。
FML バッファでは、フィールド識別子とフィールド長に 16 ビットが使用されます。
FML バッファの詳細については、「FML 型バッファ」を参照してください。
該当
該当せず
該当
該当
FML32
FML と同じ。ただし、フィールド識別子とフィールド長に 32 ビットが使用されます。より長いフィールドを多数使用できるので、バッファ全体が大きくなります。
FML32 バッファの詳細については、「FML 型バッファ」を参照してください。
該当
該当せず
該当
該当
STRING
最後が NULL 文字で終了する文字配列。STRING バッファは、自己記述型です。そのため、異なる文字セットを使用するマシン間でデータを交換する場合は、Oracle Tuxedo システムによってデータが自動的に変換されます。
該当
該当せず
該当せず
該当せず
VIEW
アプリケーションで定義される C 構造体。VIEW 型には、個々のデータ構造体を示すサブタイプが必要です。VIEW 記述ファイル (データ構造体のフィールドとタイプが定義されたファイル) は、VIEW 型バッファに定義されたデータ構造体を使用するクライアント プロセスとサーバ プロセスがアクセスできなければなりません。異なるタイプのマシン間でバッファがやり取りされる場合は、エンコード/デコードが自動的に行われます。
VIEW は、mbstring 型バッファをサポートしていません。
VIEW バッファの詳細については、「VIEW 型バッファ」を参照してください。
該当せず
該当
該当
該当
VIEW32
VIEW と同じ。ただし、長さとカウントのフィールド長に 32 ビットが使用されます。より長いフィールドを多数使用できるので、バッファ全体が大きくなります。
VIEW32 は、mbstring 型バッファをサポートしており、carray と同じ方法で mbstring データを処理します。
VIEW32 バッファの詳細については、「VIEW 型バッファ」を参照してください。
該当せず
該当
該当
該当
X_C_TYPE
VIEW と同じです。
該当せず
該当
該当
該当
X_COMMON
VIEW と同じ。ただし、このバッファ型は COBOL と C プログラム間の互換性を取るために使用されます。フィールド タイプとして使用できるのは、short、long、および string だけです。
該当せず
該当
該当
該当
XML
XML 文書は、次の要素から構成されます。
  • エンコードされた文字の並びで構成されるテキスト
  • 文書の論理構造の記述と、その構造に関する情報
XML 文書のルーティングは、要素の内容、または要素タイプと属性値に基づいて行われます。使用されている文字エンコードは XML パーサによって判別されます (Oracle Tuxedo 9.x では、XML パーサとして Apache Xerces C++ バージョン 2.5 パーサが使用可能)。エンコードが Oracle Tuxedo のコンフィグレーション ファイル (UBBCONFIG(5)DMCONFIG(5)) で使用されているネイティブな文字セット (US-ASCII または EBCDIC) と異なる場合、要素と属性名は US-ASCII または EBCDIC に変換されます。
XML バッファおよび Xerces C++ パーサの詳細については、「XML 型バッファと Apache Xerces C++ パーサ」を参照してください。
該当せず
該当せず
該当
該当せず
X_OCTET
CARRAY と同じです。
該当せず
該当せず
該当せず
該当せず
MBSTRING
Oracle Tuxedo 8.1 で使用可能になったマルチバイト文字の文字配列。MBSTRING バッファの詳細については、「MBSTRING 型バッファ」を参照してください。
該当せず
該当せず
該当せず
該当せず

すべてのバッファ タイプは、$TUXDIR/lib ディレクトリの tmtypesw.c ファイルに定義されています。クライアント プログラムとサーバ プログラムで認識されるバッファ タイプは、tmtypesw.c に定義されているものだけです。tmtypesw.c ファイルを編集して、バッファ タイプを追加したり削除できます。また、UBBCONFIGBUFTYPE パラメータを使用して、特定のサービスで処理できるタイプとサブタイプを制限できます。

tmtypesw.c ファイルは、共有オブジェクトや動的リンク ライブラリのビルドに使用されます。このオブジェクトは、Oracle Tuxedo 管理サーバ、およびアプリケーション クライアントとアプリケーション サーバによって動的にロードされます。

関連項目

 


型付きバッファの割り当て

初期状態では、バッファはクライアント プロセスに対応付けられていません。クライアント プロセスでメッセージを送信する場合、サポートされているタイプのバッファを割り当てて、メッセージを格納できるようにします。型付きバッファを割り当てるには、次に示すように tpacall(3c) 関数を使用します。

char*
tpalloc(char *
type, char *subtype, long size)

次の表は、tpalloc() 関数の引数を示しています。

表 3-2 tpalloc() 関数の引数
引数
説明
type
有効な型付きバッファを指すポインタ。
subtype
VIEW 記述ファイルVIEWVIEW32、または X_COMMON 型バッファに指定されているサブタイプの名前を指すポインタ。
subtype がない場合、この引数には NULL 値が使用されます。
size
バッファのサイズ。
Oracle Tuxedo システムにより、CARRAYX_OCTET、および XML を除くすべての型付きバッファに、自動的にデフォルトのバッファ サイズが割り当てられます。自動的にバッファ サイズが割り当てられないバッファ型には、バッファの終わりを識別できるようにサイズを指定する必要があります。
CARRAYX_OCTET、および XML を除くすべての型付きバッファのサイズにゼロが指定されると、各型付きバッファに割り当てられているデフォルト値が使用されます。サイズが指定されている場合、指定されたサイズまたはそのバッファ型に割り当てられているデフォルト値のうちの大きい方が使用されます。
STRINGCARRAYX_OCTET、および XML を除くすべての型付きバッファのデフォルト サイズは 1024 バイトです。STRING 型バッファのデフォルト サイズは 512 バイトです。CARRAYX_OCTET、および XML にデフォルト値はありません。これらの型付きバッファには、ゼロより大きな値を指定する必要があります。サイズが指定されていない場合、引数にはデフォルト値の 0 が使用されます。その結果、tpalloc() 関数は NULL ポインタを返して、tperrnoTPEINVAL を設定します。

次の例で示すように、VIEWVIEW32X_C_TYPE、および X_COMMON 型バッファには subtype 引数が必要です。

コード リスト 3-1 VIEW 型バッファの割り当て
struct aud *audv; /* VIEW 構造体 aud を指すポインタ */
. . .
audv = (struct aud *) tpalloc("VIEW", "aud", sizeof(struct aud));
. . .

次の例は、FML 型バッファの割り当て方法を示しています。subtype 引数に NULL 値が指定されていることに注目してください。

コード リスト 3-2 FML 型バッファの割り当て
FBFR *fbfr; /* FML バッファ構造体を指すポインタ */
. . .
fbfr = (FBFR *)tpalloc("FML", NULL, Fneeded(f, v))
. . .

次の例は、CARRAY 型バッファの割り当て方法を示しています。このバッファ型では、size 値を指定する必要があります。

コード リスト 3-3 CARRAY 型バッファの割り当て
char *cptr;
long casize;
. . .
casize = 1024;
cptr = tpalloc("CARRAY", NULL, casize);
. . .

処理が正常に終了すると、tpalloc() 関数は char 型のポインタを返します。STRINGCARRAY 以外のタイプでは、ポインタを適切な C 構造体または FML ポインタにキャストする必要があります。

tpalloc() 関数は、エラーを検出すると NULL ポインタを返します。次は、エラー条件の例です。

全エラー コードとその説明については、『Oracle Tuxedo C リファレンス』の「tpalloc(3c)」を参照してください。

次のコード リストは、STRING 型バッファの割り当て方法を示しています。この例では、tpalloc()size 引数の値として、デフォルト値が使用されています。

コード リスト 3-4 STRING 型バッファの割り当て
char *cptr;
. . .
cptr = tpalloc("STRING", NULL, 0);
. . .

関連項目

 


データのバッファへの格納

バッファを割り当てると、そこにデータを格納できるようになります。

次の例では、3 つのメンバー (フィールド) を持つ VIEW 型バッファ aud を作成しています。3 つのメンバーは、コマンドラインがある場合はそこから取得される支店識別子の b_id、照会された残高を返す balance、およびステータス行にメッセージを返す ermsg です。audit を使用して特定の支店の残高が照会されると、b_id の値には要求の送信先の支店識別子、balance にはゼロ、ermsg には NULL 文字列がそれぞれ設定されます。

コード リスト 3-5 メッセージ バッファへのデータの格納 - 例 1
...
audv = (struct aud *)tpalloc("VIEW", "aud", sizeof(struct aud));

/* aud 構造体を用意する */

audv->b_id = q_branchid;
audv->balance = 0.0;
(void)strcpy(audv->ermsg, "");
...

audit を使用して銀行全体の残高が照会されると、BAL サーバが呼び出されてサイトごとの残高合計が取得されます。個々のサイトで照会を行うには、代表支店識別子を指定します。代表支店 ID は、配列 sitelist[] に格納されます。したがって、aud 構造体は、次の例のように設定されます。

コード リスト 3-6 メッセージ バッファへのデータの格納 - 例 2
...
/* aud 構造体を用意する */

audv->b_id = sitelist[i];/* このフィールドでルーティング */
audv->balance = 0.0;
(void)strcpy(audv->ermsg, "");
...

STRING バッファにデータを格納するプロセスについては、「バッファのサイズ変更」のコード リストを参照してください。

関連項目

 


型付きバッファのサイズの変更

tpalloc() で割り当てられたバッファのサイズを変更するには、次のように tprealloc(3c) 関数を使用します。

char*
tprealloc(char *ptr, long size)

次の表は、tprealloc() 関数の引数を示しています。

表 3-3 tprealloc() 関数の引数
引数
説明
ptr
サイズを変更するバッファを指すポインタ。このポインタは、tpalloc() の呼び出しで設定されます。それ以外の方法で設定されている場合、呼び出しは失敗し、tperrno(5)TPEINVAL に設定されて、無効な引数がこの関数に渡されたことが示されます。
size
変更後のバッファ サイズを指定する長精度型 (long)。

tprealloc() が返すポインタは、元のバッファと同じタイプのバッファを指します。バッファの場所が変わっている場合があるので、返されたポインタを使用してサイズが変更されたバッファを参照します。

バッファのサイズを増やすために tprealloc() 関数を呼び出すと、バッファに新しい領域が割り当てられます。バッファのサイズを減らすために tprealloc() 関数を呼び出すと、実際にバッファのサイズが変更されるのでなく、指定されたサイズを超える領域が使用不能になります。型付きバッファの内容には影響しません。未使用領域を解放するには、必要なサイズを持つ別のバッファにデータをコピーし、未使用領域を持つバッファを解放します。

tprealloc() 関数は、エラーが発生すると NULL ポインタを返し、tperrno に適切な値を設定します。エラー コードについては、『Oracle Tuxedo C リファレンス』の「tpalloc(3c)」を参照してください。

警告 : tprealloc() 関数が NULL ポインタを返した場合、内容が変更されて有効ではなくなったバッファが渡された可能性があります。

次のコード リストは、STRING バッファの領域を再度割り当てる方法を示しています。

コード リスト 3-7 バッファのサイズ変更
#include <stdio.h>
#include “atmi.h”

char instr[100]; /* 標準入力からの入力文字列を格納する文字列 */
long s1len, s2len; /* 文字列 1 と文字列 2 の長さ */
char *s1ptr, *s2ptr; /* 文字列 1 と文字列 2 のポインタ */

main()

{
(void)gets(instr); /* 標準入力から行を取得 */
s1len = (long)strlen(instr)+1; /* 長さを決定 */

join application

if ((s1ptr = tpalloc(“STRING”, NULL, s1len)) == NULL) {
fprintf(stderr, “tpalloc failed for echo of: %s\n”, instr);
leave application
exit(1);
}
(void)strcpy(s1ptr, instr);

make communication call with buffer pointed to by s1ptr

(void)gets(instr); /* 標準入力から別の行を取得 */
s2len = (long)strlen(instr)+1; /* その長さを決定 */
if ((s2ptr = tprealloc(s1ptr, s2len)) == NULL) {
fprintf(stderr, “tprealloc failed for echo of: %s\n”, instr);
free s1ptr's buffer
leave application
exit(1);
}
(void)strcpy(s2ptr, instr);

make communication call with buffer pointed to by s2ptr
. . .
}

次の例は前述の例を拡張したもので、発生する可能性があるエラー コードを確認する方法を示しています。

コード リスト 3-8 tprealloc() のエラーの確認
. . .
if ((s2ptr=tprealloc(s1ptr, s2len)) == NULL)
switch(tperrno) {
case TPEINVAL:
fprintf(stderr, "given invalid arguments\n");
fprintf(stderr, "will do tpalloc instead\n");
tpfree(s1ptr);
if ((s2ptr=tpalloc("STRING", NULL, s2len)) == NULL) {
fprintf(stderr, "tpalloc failed for echo of: %s\n", instr);
leave application
exit(1);
}
break;
case TPEPROTO:
fprintf(stderr, "tried to tprealloc before tpinit;\n");
fprintf(stderr, "program error; contact product support\n");
leave application
exit(1);
case TPESYSTEM:
fprintf(stderr,
"BEA Tuxedo error occurred; consult today's userlog file\n");
leave application
exit(1);
case TPEOS:
fprintf(stderr, "Operating System error %d occurred\n",Uunixerr);
leave application
exit(1);
default:
fprintf(stderr,
"Error from tpalloc: %s\n", tpstrerror(tperrno));
break;
}

関連項目

 


バッファ タイプの確認

tptypes(3c) 関数は、バッファのタイプとサブタイプ (指定されている場合) を返します。次は tptypes() 関数の文法です。

long
tptypes(char *ptr, char *type, char *subtype)

次の表は、tptypes() 関数の引数を示しています。

表 3-4 tptypes() 関数の引数
引数
説明
ptr
データ バッファを指すポインタ。このポインタは、tpalloc() または tprealloc() の呼び出しで設定されます。NULL は指定できません。また、文字型にキャストする必要があります。この 2 つの条件が満たされていない場合、tptypes() 関数は引数が無効であることを示すエラーを返します。
type
データ バッファのタイプを指すポインタ。type は文字型の値です。
subtype
データ バッファのサブタイプ (指定されている場合) を指すポインタ。subtype は文字型の値です。VIEWVIEW32X_C_TYPE、および X_COMMON 以外のタイプの場合、返された subtype パラメータは NULL 文字列を含む文字配列を指します。

処理が正常に終了した場合、tptypes() 関数は長精度型 (long) でバッファの長さを返します。

エラーが発生した場合、tptypes() 関数は -1 を返し、tperrno(5) に対応するエラー コードを設定します。エラー コードについては、『Oracle Tuxedo C リファレンス』の「C 言語アプリケーション トランザクション モニタ インタフェースについて」および「tpalloc(3c)」を参照してください。

処理の正常終了時に tptypes() 関数から返されたサイズ値を使用して、次の例に示すように、デフォルトのバッファ サイズがデータを格納するのに十分な大きさかどうかを確認できます。

コード リスト 3-9 バッファ サイズの取得
. . .
iptr = (FBFR *)tpalloc("FML", NULL, 0);
ilen = tptypes(iptr, NULL, NULL);
.. .
if (ilen < mydatasize)
iptr=tprealloc(iptr, mydatasize);

関連項目

 


型付きバッファの解放

tpfree(3c) 関数は、tpalloc() で割り当てられたバッファ、または tprealloc() で再度割り当てられたバッファを解放します。次は tpfree() 関数の文法です。

void
tpfree(char *ptr)

tpfree() 関数の引数は、次の表に示す ptr だけです。

表 3-5 tpfree() 関数の引数
引数
説明
ptr
データ バッファを指すポインタ。このポインタは、tpalloc() または tprealloc() の呼び出しで設定されます。NULL は指定できません。また、文字型にキャストする必要があります。この 2 つの条件が満たされていない場合、この関数は何も解放しないか、エラー条件を通知しないで制御を戻します。

tpfree() を使用して FML32 バッファを解放するとき、ルーチンは埋め込まれたバッファをすべて再帰的に解放して、メモリ リークの発生を防ぎます。埋め込みバッファが解放されないようにするには、対応するポインタに NULL を指定してから tpfree() ルーチンを発行します。ptr が NULL の場合、何も処理は行われません。

次のコード リストは、tpfree() 関数を使用してバッファを解放する方法を示しています。

コード リスト 3-10 バッファの解放
struct aud *audv; /* VIEW 構造体 aud を指すポインタ */
. . .
audv = (struct aud *) tpalloc("VIEW", "aud", sizeof(struct aud));
. . .
tpfree((char *)audv);

関連項目

 


VIEW 型バッファ

VIEW 型バッファには 2 種類あります。1 つは FML VIEW で、FML バッファから生成される C 構造体です。もう 1 つは、単なる非依存型の C 構造体です。

FML バッファを C 構造体に変換して再び元に戻す (FML VIEW 型バッファを使用する) のは、FML 型バッファでの処理にはオーバーヘッドが生じるからです。つまり FML 型バッファには、データの独立性と操作の利便性がある一方で、FML 関数を呼び出すためのオーバーヘッドが発生します。C 構造体は、柔軟性の点では劣りますが、バッファ データの時間がかかる処理に適しています。大量のデータを操作する場合、フィールド化バッファのデータを C 構造体に転送し、通常の C 関数を使用してそのデータを処理し、格納やメッセージ転送を行うためにそのデータを FML 型バッファに戻すと、パフォーマンスを向上させることができます。

FML 型バッファと FML ファイルの変換の詳細については、『Oracle Tuxedo FML リファレンス』を参照してください。

VIEW 型バッファを使用するには、次の手順に従います。

VIEW 型バッファの環境変数の設定

アプリケーションで VIEW 型バッファを使用するには、次の環境変数を設定します。

表 3-6 VIEW 型バッファの環境変数の設定
環境変数
説明
FIELDTBLS または FIELDTBLS32
FML または FML32 型バッファのフィールド テーブル ファイル名のカンマ区切りのリスト。FML VIEW 型のみで必要です。
FLDTBLDIR または FLDTBLDIR32
FML または FML32 型バッファのフィールド テーブル ファイルが検索されるディレクトリのコロン区切りのリスト。Microsoft Windows では、セミコロンで区切られます。FML VIEW 型のみで必要です。
VIEWFILES または VIEWFILES32
VIEW または VIEW32 記述ファイルに使用されるファイル名のカンマ区切りのリスト。
VIEWDIR または VIEWDIR32
VIEW または VIEW32 ファイルが検索されるディレクトリのコロン区切りのリスト。Microsoft Windows では、セミコロンで区切られます。

VIEW 記述ファイルの作成

VIEW 型バッファを使用するには、VIEW 記述ファイルに C 言語のレコードを定義する必要があります。VIEW 記述ファイルには、各エントリの VIEW、および C 構造体のマッピングと FML 変換パターンを記述した VIEW が定義されています。VIEW の名前は、C 言語の構造体の名前に対応します。

VIEW 記述ファイルの各構造体は、次の形式で定義します。

$ /* VIEW 構造体 */
VIEW viewname
type cname fbname count flag size null

次の表は、VIEW 記述ファイルに指定する必要がある各 C 構造体のフィールドを示しています。

表 3-7 VIEW 記述ファイルのフィールド
フィールド
説明
type
フィールドのデータ型。shortlongfloatdoublecharstring、または carray を指定できます。

注意 : mbstring データ型は、VIEW32 型付きバッファのみでサポートされます。

cname
C 構造体のフィールド名。
fbname
FML から VIEW、または VIEW から FML への変換関数を使用する場合、対応する FML 名をこのフィールドに指定する必要があります。このフィールド名は、FML フィールド テーブル ファイルにも必要です。FML に依存しない VIEW には必要ありません。
count
フィールドの出現回数。
flag
次のいずれかのオプション フラグを指定します。
  • P - NULL 値の解釈を変更します。
  • S - フィールド化バッファから構造体に一方向のマッピングを行います。
  • F - 構造体からフィールド化バッファへの一方向マッピングを行います。
  • N - ゼロ方向のマッピングを行います。
  • C - 連想カウント メンバー (ACM) に追加フィールドを生成します。
  • L - STRINGCARRAY、および MBSTRING に転送されるバイト数を保持します。

注意 : view32 コマンドは、MBSTRING 型バッファの L オプション フラグを自動的に追加します。

size
STRING または CARRAY 型レコードの最大長を指定します。それ以外のバッファ タイプでは、このフィールドは無視されます。
null
ユーザ定義の NULL 値、または - の場合はフィールドのデフォルト値。VIEW 型バッファで使用される NULL 値は、空の C 構造体を示します。
数値型の場合、デフォルトの NULL 値は 0 (dec_t の場合は 0.0) になります。文字型の場合、デフォルトの NULL 値は \0 になります。STRING 型、CARRAY 型、および MBSTRING 型の場合、デフォルトの NULL 値は “ ” になります。
エスケープ文字として使用されている定数も、NULL 値の指定に使用できます。VIEW コンパイラで認識されるエスケープ定数は、\ddd (d は 8 進数)、\0\n\t\v\r\f\\\’、および \” です。
STRINGCARRAYMBSTRING、および char 型の NULL 値は、二重引用符または一重引用符で囲みます。VIEW コンパイラでは、ユーザ定義の NULL 値でエスケープされていない引用符は使用できません。
VIEW メンバー記述の NULL フィールドにキーワード NONE を指定することもできます。このキーワードは、そのメンバーの NULL 値がないことを示します。文字列メンバーおよび文字配列メンバーのデフォルト値の最大サイズは、2660 文字です。詳細については、『Oracle Tuxedo FML リファレンス』を参照してください。

行頭に # または $ 文字を付けてコメント行を挿入できます。行頭に $ が挿入されたコード行は、.h ファイルに出力されます。

次のコード リストは、FML バッファに基づく VIEW 記述サンプル ファイルの一部です。このコード リストでは、fbname フィールドを指定する必要があり、この値は対応するフィールド テーブル ファイルの値と一致していなければなりません。CARRAY1 フィールドのオカレンス カウントが 2 に設定されていること、C フラグが設定されて追加のカウント要素の作成が定義されていることに注目してください。また、L フラグが設定され、アプリケーションが CARRAY1 フィールドを格納するときの文字数を示す長さ要素が定義されています。

コード リスト 3-11 FML VIEW の VIEW 記述ファイル
$ /* VIEW 構造体 */
VIEW MYVIEW
#型 cname fbname カウント フラグ サイズ null
float float1 FLOAT1 1 - - 0.0
double double1 DOUBLE1 1 - - 0.0
long long1 LONG1 1 - - 0
short short1 SHORT1 1 - - 0
int int1 INT1 1 - - 0
dec_t dec1 DEC1 1 - 9,16 0
char char1 CHAR1 1 - - '\0'
string string1 STRING1 1 - 20 '\0'
carray carray1 CARRAY1 2 CL 20 '\0'
END

次のコード リストは、同じ VIEW 記述ファイルで非依存型 VIEW のものを示しています。

コード リスト 3-12 非依存型 VIEW の VIEW 記述ファイル
$ /* VIEW データ構造体 */
VIEW MYVIEW
#型 cname fbname カウント フラグ サイズ null
float float1 - 1 - - -
double double1 - 1 - - -
long long1 - 1 - - -
short short1 - 1 - - -
int int1 - 1 - - -
dec_t dec1 - 1 - 9,16 -
char char1 - 1 - - -
string string1 - 1 - 20 -
carray carray1 - 2 CL 20 -
END

この形式は FML 依存型 VIEW と同じです。ただし、fbname フィールドと null フィールドには意味がなく、viewc コンパイラで無視されます。これらのフィールドには、プレースホルダとしてダッシュ (-) などの値を挿入する必要があります。

VIEW コンパイラの実行

VIEW 型バッファをコンパイルするには、引数として VIEW 記述ファイルの名前を指定して viewc コマンドを実行します。非依存型 VIEW を指定するには、-n オプションを使用します。生成される出力ファイルを書き込むディレクトリを指定することもできます (省略可能)。デフォルトでは、出力ファイルはカレント ディレクトリに書き込まれます。

たとえば、FML 依存型 VIEW をコンパイルするには、次のようにコンパイラを実行します。

viewc myview.v
注意 : VIEW32 型バッファをコンパイルするには、viewc32 コマンドを実行します。

非依存型 VIEW の場合、コマンドラインで次のように -n オプションを指定します。

viewc -n myview.v

viewc コマンドでは、次が出力されます。

次のコード リストは、viewc によって生成されるヘッダ ファイルを示しています。

コード リスト 3-13 VIEW コンパイラによって生成されるヘッダ ファイル
struct MYVIEW {
float float1;
double double1;
long long1;
short short1;
int int1;
dec_t dec1;
char char1;
char string1[20];
unsigned short L_carray1[2]; /* carray1 の長さを挿入する配列 */
short C_carray1; /* carray1 のカウント */
char carray1[2][20];
};

FML 依存型と FML 非依存型 VIEW にも、同じヘッダ ファイルが生成されます。

クライアント プログラムまたはサービス サブルーチンで VIEW 型バッファを使用するには、アプリケーションの #include 文にヘッダ ファイルを指定する必要があります。

関連項目

 


FML 型バッファ

FML 型バッファを使用するには、次の手順に従います。

FML 関数は、フィールド化バッファから C 構造体への変換、またその逆の変換など、型付きバッファを操作する場合に使用します。これらの関数を使用すると、データ構造やデータの格納状態がわからなくても、データ値にアクセスしたり更新できます。FML 関数の詳細については、『Oracle Tuxedo FML リファレンス』を参照してください。

FML 型バッファの環境変数の設定

アプリケーション プログラムで FML 型バッファを使用するには、次の環境変数を設定する必要があります。

表 3-8 FML 型バッファの環境変数
環境変数
説明
FIELDTBLS または FIELDTBLS32
FML または FML32 型バッファのフィールド テーブル ファイル名のカンマ区切りのリスト。
FLDTBLDIR または FLDTBLDIR32
FML または FML32 型バッファのフィールド テーブル ファイルが検索されるディレクトリのコロン区切りのリスト。Microsoft Windows では、セミコロンで区切られます。

フィールド テーブル ファイルの作成

FML 型バッファや FML 依存型 VIEW を使用する場合は、常にフィールド テーブル ファイルが必要です。フィールド テーブル ファイルは、FML 型バッファのフィールドの論理名をそのフィールドをユニークに識別する文字列にマッピングします。

FML フィールド テーブルの各フィールドは、次の形式で定義します。

$ /* FML 構造体 */
*base value
name number type flags comments

次の表は、FML フィールド テーブルに指定する必要がある FML フィールドを示しています。

表 3-9 フィールド テーブル ファイルのフィールド
フィールド
説明
*base value
後続のフィールド番号をオフセットするためのベース値。関連するフィールドのセットを簡単にグループ分けし、番号を付け直すことができるようになります。*base オプションを使用すると、フィールド番号を再利用できます。16 ビットのバッファの場合、ベース値とそれに関連する番号を加算した値が、100 以上 8191 未満でなければなりません。このフィールドは省略可能です。

注意 : Oracle Tuxedo システムでは、フィールド番号 1 ~ 100 と 6,000 ~ 7,000 は、内部使用のために予約されています。FML ではフィールド番号 101 ~ 8,191、FML32 ではフィールド番号 101 ~ 33、554、および 431 がアプリケーション定義のフィールド用に使用できます。

name
フィールドの識別子。この値は 256 文字以下の文字列で、英数字とアンダースコア文字だけを指定できます。
rel-number
フィールドの相対数値。現在のベース値が指定されている場合、この値は現在のベース値に加算されて、フィールド番号が計算されます。
type
フィールドのタイプ。指定できるのは、charstringshortlongfloatdouble、または carray です。
flag
将来使用するために予約されたフィールド。プレースホルダとしてダッシュ (-) を挿入します。
comment
コメント (省略可能)。

すべてのフィールドは省略可能です。また、複数個使用できます。

次のコード リストは、FML 依存型 VIEW ので使用されるフィールド テーブル ファイルを示しています。

コード リスト 3-14 FML VIEW のフィールド テーブル ファイル
# 名前       番号    型     フラグ   コメント
FLOAT1 110 float - -
DOUBLE1 111 double - -
LONG1 112 long - -
SHORT1 113 short - -
INT1 114 long - -
DEC1 115 string - -
CHAR1 116 char - -
STRING1 117 string - -
CARRAY1 118 carray - -

FML ヘッダ ファイルの作成

クライアント プログラムやサービス サブルーチンで FML 型バッファを使用するには、FML ヘッダ ファイルを作成して、アプリケーションの #include 文にそのヘッダ ファイルを指定する必要があります。

フィールド テーブル ファイルから FML ヘッダ ファイルを作成するには、mkfldhdr(1) コマンドを使用します。たとえば、myview.flds.h というファイルを作成するには、次のコマンドを入力します。

mkfldhdr myview.flds

FML32 型バッファの場合は、mkfldhdr32 コマンドを使用します。

次のコード リストは、mkfldhdr コマンドによって作成される myview.flds.h ヘッダ ファイルを示しています。

コード リスト 3-15 myview.flds.h ヘッダ ファイル
/*       fname    fldid            */
/* ----- ----- */

#define FLOAT1 ((FLDID)24686) /* 番号 : 110 タイプ : float */
#define DOUBLE1 ((FLDID)32879) /* 番号 : 111 タイプ : double */
#define LONG1 ((FLDID)8304) /* 番号 : 112 タイプ : long */
#define SHORT1 ((FLDID)113) /* 番号 : 113 タイプ : short */
#define INT1 ((FLDID)8306) /* 番号 : 114 タイプ : long */
#define DEC1 ((FLDID)41075) /* 番号 : 115 タイプ : string */
#define CHAR1 ((FLDID)16500) /* 番号 : 116 タイプ : char */
#define STRING1 ((FLDID)41077) /* 番号 : 117 タイプ : string */
#define CARRAY1 ((FLDID)49270) /* 番号 : 118 タイプ : carray */

アプリケーションの #include 文に新しいヘッダ ファイルを指定します。ヘッダ ファイルがインクルードされると、シンボリック名でフィールドを参照できるようになります。

関連項目

 


XML 型バッファと Apache Xerces C++ パーサ

XML がデータ標準として受け入れられるに伴い、アプリケーションで XML 型付きバッファを使用する Oracle Tuxedo ユーザが増加しています。この動きを後押しするため、Oracle Tuxedo ソフトウェアでは Apache Xerces C++ バージョン 2.5 パーサが統合されました。

この節では、以下の内容について説明します。

XML 型バッファ

XML バッファを使用すると、Oracle Tuxedo アプリケーションで XML を使用して、アプリケーション内やアプリケーション間でデータを交換できるようになります。Oracle Tuxedo アプリケーションでは、単純 XML 型バッファの送受信や、それらのバッファを適切なサーバにルーティングできます。解析など、XML 文書のすべての処理ロジックはアプリケーション側にあります。

XML 文書は、次の要素から構成されます。

XML 型バッファのプログラミング モデルは、CARRAY 型バッファのモデルと類似しています。tpalloc() 関数を使用して、バッファの長さを指定する必要があります。最大 4 GB の XML 文書がサポートされます。

イベント処理で行われるフォーマット処理とフィルタ処理は、STRING 型バッファが使用されている場合はサポートされますが、XML 型バッファではサポートされません。そのため、XML 型バッファのバッファ タイプ スイッチ内の _tmfilter 関数と _tmformat 関数のポインタは、NULL に設定されます。

Oracle Tuxedo システムの XML パーサは、次の操作を行います。

XML 型バッファでは、データ依存型ルーティングがサポートされています。XML 文書のルーティングは、要素の内容、または要素タイプと属性値に基づいて行われます。使用される文字エンコードは XML パーサによって判別されます。エンコードが Oracle Tuxedo のコンフィグレーション ファイル (UBBCONFIGDMCONFIG) で使用されているネイティブな文字セット (US-ASCII または EBCDIC) と異なる場合、要素と属性名は US-ASCII または EBCDIC に変換されます。

XML 文書には、ルーティング用にコンフィグレーションする属性を含めなければなりません。属性がルーティング基準としてコンフィグレーションされていても XML 文書に含まれていない場合、ルーティング処理は失敗します。

要素の内容と属性値は、ルーティング フィールド値の構文とセマンティクスに従っていることが必要です。また、ルーティング フィールド値のタイプも指定しなければなりません。XML でサポートされるのは文字データだけです。範囲フィールドが数値の場合、そのフィールドの内容や値はルーティング処理時に数値に変換されます。

Apache Xerces C++ パーサ

Xerces-C++ 2.5.0 パーサは、移植可能な C++ サブセットで記述され、XML 文書を解析、生成、操作、および検証するための共有ライブラリを備えています。また、XML 1.0 勧告、および関連標準の DOM 1.0、DOM 2.0、SAX 1.0、SAX 2.0、Namespaces、および W3C の XML スキーマ勧告バージョン 1.0 に準拠しています。

Xerces-C++ 1.7 パーサは、検証が必要なときに文書型定義 (DTD) と XML スキーマ ファイルをキャッシュせず、DTD で使用される外部エンティティ ファイルもキャッシュしません。Oracle Tuxedo 8.1 では、Web で繰り返し取得される外部 DTD、スキーマ、およびエンティティ ファイルをキャッシュするオプションを追加することによって Xerces-C++ 1.7 パーサの性能が向上ました。この変更の継続的なサポートは、Tuxedo 9.x および Xerces C++ 2.5.0 で使用可能です。

XML パーサの制御

Xerces-C++ パーサのキャッシュ機能を有効または無効にする方法は次の 2 通りです。

注意 : 4 つのメソッドは、Apache Xerces-C++ パーサに加えられた Oracle Tuxedo の拡張機能です。以下の 2 つの Xerces オブジェクトと組み合わせて排他的に使用されます。

XML パーサでの ICU のサポート

Oracle Tuxedo 配布キットには、さまざまなプラットフォーム上で 200 種類を超えるエンコード文字セット (エンコード形式) をサポートする C/C++ ライブラリ、International Components for Unicode (ICU) 3.0 ライブラリが付属しています。Xerces-C++ 2.5.0 パーサは、ICU 3.0 ライブラリと共に構築されます。

XML パーサのサンプル アプリケーション

Xerces-C++ パーサ ATMI 関数を使用するためのサンプル アプリケーションは、Oracle Tuxedo ユーザ マニュアルに記載されています。このサンプルには、Xerces-C++ パーサのラッパーを記述して、C で記述された Tuxedo クライアントおよびサーバから Xerces-C++ ATMI 関数を呼び出せるようにするための方法が示されています。

Xerces スキーマのサンプル

Xerces パーサで XML スキーマを使用するためのサンプル アプリケーションは、Oracle Tuxedo ユーザ マニュアルに記載されています。『サンプルを使用した Oracle Tuxedo アプリケーションの開発方法』の「xmlfmlapp (完全な C XML/FML32 変換アプリケーション) のチュートリアル

関連項目

getURLEntityCacheDir(3c)setURLEntityCacheDir(3c)getURLEntityCaching(3c)setURLEntityCaching(3c)Xerces API パーサのオンライン マニュアル

XML データと FML/FML32 バッファ間の変換

入力/出力形式として、XML データは、現在のアプリケーション開発で幅広く使用されています。一方、ほとんどの Tuxedo カスタマは、望ましいデータ転送として Tuxedo FML/FML32 バッファを使用する既存の定義済みサービスに多額の投資を行っています。

Oracle Tuxedo は、XML と FML/FML32 バッファ間のデータ変換が可能な機能を追加して、この問題に対処します。この変換は、次のいずれかの方法で開始できます。

変換に使用されるメソッドに関係なく、FML/FML32 フィールド型は、特定の方法で XML にマッピングされます。変換マッピングの詳細については、「XML と FML/FML32 フィールド型のマッピング」を参照してください。

注意 : XML と FML/FML32 間の変換では、サイズが大きくなる可能性があるサード パーティ ライブラリ (libticudata.so など) を使用します。
注意 : 共有ライブラリのサイズが大きくなると、そのライブラリに直接または間接的に依存する、Tuxedo アプリケーションで実行中のプロセスが多くのメモリを消費し、その結果、パフォーマンスが低下する可能性があります。
注意 : XML と FML/FML32 間の変換機能は、Tuxedo システム プロセスでは使用しないでください。
注意 : Xerces パーサを使用した XML と FML/FML32 バッファ間の変換の制限に関するその他の既知の問題については、「変換の制限事項」を参照してください。

オンデマンド変換の使い方

オンデマンド変換では、XML データから FML/FML32 バッファまたは FML/FML32 バッファから XML データへの変換を手動で実行できます。

次の 4 つの ATMI 関数では、オンデマンド変換を実行できます。

これらの関数と引数の詳細な説明については、『Oracle Tuxedo C リファレンス』を参照してください。

オンデマンド変換を開始する

XML データと FML/FML32 バッファ間のオンデマンド変換を実行するには、次の手順に従います。

オンデマンド変換と Xerces パーサ XML 検証

ATMI 関数を使用して XML と FML/FML32 バッファ間の変換を開始する場合は、次のいずれかの方法でパーサ検証が決定されます。

ATMI 関数とその Xerces パーサの flag 引数の詳細な説明については、『BEA Tuxedo C リファレンス』を参照してください。

自動変換の使い方

自動変換では、最初の形式も最後の形式も XML になります。つまり、XML バッファが FML/FML32 バッファに入力、変換、および処理され、最後に XML に再変換されます。

XML と FML/FML32 バッファ間の変換を開始するには、UBBCONFIG ファイルの SERVICES セクションの BUFTYPECONV パラメータを指定する必要があります。このパラメータは、XML2FML または XML2FML32 のどちらかの値のオプションのみを受け付けます。

このパラメータを使用してサーバを起動した場合、クライアント tpcall()tpacall()tpconnect()、または tpsend() によって入力バッファが XML バッファから FML/FML32 バッファに変換されてからサービスに送られます。tpreturn() または tpsend() が呼び出されると、FML/FML32 バッファが XML バッファに変換されてから返されます。

BUFTYPECONV パラメータを使用しているサービスでは、クライアントまたはその他のサービスは、既存のサービスが FML/FML32 バッファを処理する方法を変更することなく、XML バッファを送受信できます。

注意 : BUFTYPECONV パラメータを使用する場合は、以下の項目に注意してください。

自動変換の際に、入力 XML ルート要素名を保存することはできないので、出力 XML ルート タグは、デフォルト ルート タグ <FML Type="FML"> または <FML Type="FML32"> を使用します。

自動変換を開始する

XML データと FML/FML32 バッファ間の自動変換を実行するには、次の手順に従います。

自動変換と Xerces パーサ XML 検証

Xerces パーサは、デフォルトの属性設定を使用して、自動変換時の XML 検証を制御します。ただし、Tuxedo では 14 個の固有の Xerces DOMParser クラス属性をサポートしており、これらを使用することで自動変換を多少柔軟にカスタマイズできます。

自動変換メソッドを使用している場合、パーサ検証は以下のいずれかの方法で決定されます。

以下のリストは、TPXPARSFILE 環境変数のサンプル入力プレーン テキスト ファイルです。

コード リスト 3-16 TXPARSFILE 環境変数のサンプル入力

CacheGrammarFromParse=True
DoNameSpaces=True
DoSchema=True
ExternalSchemaLocation= http://www.xml.org/sch.xsd
ExitOnFirstFatalError=c:\xml\example.xsd
IncludeIgnorableWhiteSpace=True
LoadGrammar=
NoNamespaceSchemaLocation=
StandardUriConformant=True
UseCachedGrammarInParse=True
UseScanner=WF
ValidationConstraintFatal=True
ValidationScheme=Val_Auto
ValidationSchemaFullChecking=True

XML と FML/FML32 フィールド型のマッピング

XML 形式と FML/FML32 フィールド間の関係では、XML 要素名は FML/FML32 フィールド名と同じですが、XML 値は対応するフィールド型をもとに解釈されます。

開始および終了タグは、フィールドの名前を使用します。属性は、必要に応じて FLD_FML32、FLD_MBSTRINGFLD_VIEW32 で提供されます。フィールド名と属性の大文字と小文字は区別されます。

フィールド値は文字列として読み取られ、以下のフィールド型に変換されます。

<FIELDNAME Attribute="Attribute Value"> FIELDVALUE </FIELDNAME>

FML/FML32 フィールド型は、次のように XML バッファ型にマッピングされます。

フィールド タイプ
変換マッピング
SHORT
LONG
CHAR
FLOAT
DOUBLE
STRING
FLD_SHORTFLD_LONG、FLD_CHARFLD_FLOAT, FLD_DOUBLE、および FLD_STRING フィールドと XML 文字列値間の変換は単純です。
型の値の形式は、Ftypcvt() で使用されているスタイルに従います。
FML:AMOUNT=10.00
XML:<AMOUNT>10.00</AMOUNT>
CARRAY
FLD_CARRAY フィールドの変換時に、Tuxedo では、XML バイト ストリーム値は XML の 2 文字から 1 バイト値に変換されます。つまり、文字の各 XML ペアは 16 バイト値を表します。
FML: BEA=TUXEDO
XML:<BEA>54555845444F</BEA>
PTR

XML への変換時に、FLD_PTR フィールド名は、STRINGMBSTRINGCARRAYFMLFML32、および VIEW32 のうち、有効な Tuxedo バッファ型を示し、無効なバッファ型を無視します。バッファの内容が XML に変換された場合、BUFTYPE 属性はバッファ型タグに含まれます (例 1 を参照)。

FML32 への変換時に、BUFTYPE 属性をバッファ型タグに含める必要があります。有効な唯一の値は、STRINGMBSTRINGCARRAYFMLFML32、および VIEW32 の Tuxedo バッファ型です。BUFTYPE 属性を指定していない場合、または無効な値を使用している場合、要素は FML32 で無視されます。

例 1 - XML 変換
<stringptr BUFTYPE=”STRING”>teststringptr</stringptr>
例 2 - FML32 変換
<fml32ptr BUFTYPE=”FML32”><id>2323</id>
</fml32ptr>
FML32
FLD_FML32 フィールド名は、FML フィールド名に基づいて開始および終了タグでサポートされます。この XML 文書には、バッファに含まれるフィールドごとに <fieldname>value</fieldname> の複数の説明が含まれます。
埋め込み FML32 は許可されるので、XML の階層記述は受け付けられます。

注意 : 省略可能な属性 Tpmbenc は、XML と FML32 間の変換時に FML32 バッファの MBSTRING フィールド全体のエンコードを指定するために使用します。

下記の最初の例には、エンコード属性が含まれます。2 番目の例は、ID という埋め込み FML32 フィールドを含む BANK フィールドに対する FML32 定義です。
例 1:
<ACCT Tpmbenc="EUC"><NM>Smith</NM><TRAN>OPEN</TRAN></ACCT>
例 2: <BANK><BID>001</BID><ID><NM>Jones</NM><AC>001</AC></ID>
</BANK>
VIEW32
FLD_VIEW32 フィールド名がサポートされているので、FLD_INT フィールドと FLD_DECIMAL フィールドも認識されます。FLD_INT は、FLD_LONG と同様に処理されます。
開始および終了タグは、FLD_VIEW32 フィールド名を基づいています。使用する VIEW 名を指定するために Vname 属性が取られます。この XML 文書には、次の記述が複数含まれています。
<fbname> value </fbname>
fbname は、VIEW メンバー フィールドのバッファ名です。
<CURR Vname="Myview"> <FB1>001</FB1><FB1>002</FB1><FB2>7.50</FB2><FB3>Y</FB3>
</CURR>
MBSTRING
FLD_MBSTRING フィールド変換は、Encoding 属性、および FML32 フィールドを記述するためのフィールド データを使用します。この変換は、Fmbpack32 を使用した場合と同じです。次の条件に注意してください。
  1. Encoding 属性があり、値が指定されている場合、データ値を基に FLD_MBSTRING 値が作成されます。
  2. Encoding 属性がなく、Tpmbenc が完全な FML32 バッファ用に設定されている場合、FLD_MBSTRINGTpmbenc 値を適用します。
  3. Encoding 属性がなく、Tpmbenc も指定されていない場合、プロセス環境 TPMBENC (すべて大文字) の取得が試みられ、属性定義の代わりに FLD_MBSTRING 値としてそのエンコードが使用されます。
  4. 上記の 3 つの条件のいずれにも当てはまらない場合、それらの要素は無視され、変換は実行されません。
データは、FLD_CARRAY フィールドと同じ方法で処理されます。
<MBIN Encoding="SJIS">C7E8D9CAB3</MBIN>

変換の制限事項

Tuxedo で提供されている Xerces 2.5.0 パーサを使用した XML データと FML/FML32 バッファ間の変換には、次の制限事項があります。

関連項目

 


MBSTRING 型バッファ

中国語、日本語、韓国語、およびその他のアジア太平洋言語で必要とされるマルチバイトエンコード文字セットをサポートするために、Oracle Tuxedo には、マルチバイト文字のユーザ データを転送するための MBSTRING 型付きバッファが用意されています。中国語、日本語、韓国語、およびその他のアジア太平洋言語では、文字を表現するために複数バイトを使用するエンコード文字セットが使用されます。

MBSTRING 型付きバッファおよびマルチバイト文字エンコード機能を使用すると、Oracle Tuxedo システムは、プロセス間で MBSTRING バッファ (または FML32 バッファの FLD_MBSTRING フィールド) が転送されるときに、ユーザ データを別のエンコード表現に変換できます。次の図は、エンコード変換がどのように行われるかを例示しています。

図 3-1 MBSTRING バッファによるエンコード変換の例

MBSTRING バッファによるエンコード変換の例

上図の例に示すように、MBSTRING 型付きバッファは、ユーザ データのコード セット文字エンコード (または単にエンコード) を識別する情報を保持できます。この例では、クライアントの要求の MBSTRING バッファは、Shift-JIS (SJIS) エンコードで表される日本語ユーザ データを保持し、サーバの応答の MBSTRING バッファは、Extended UNIX Code (EUC) エンコードで表される日本語ユーザ データを保持しています。マルチバイト文字エンコード機能では、環境変数 TPMBENCTPMBACONV を読み込んで、ソースのエンコード、ターゲットのエンコード、および自動エンコード変換の状態 (有効または無効) を判別します。

エンコードの変換機能により、基底の Tuxedo システム ソフトウェアでは、着信メッセージのエンコード表現を、受信プロセスが実行されているマシンでサポートされているエンコード表現に変換できます。この変換は文字コード セット間の変換でも言語の翻訳でもなく、同じ言語の異なる文字エンコード間の変換です。

マルチバイト文字エンコードの制御

文字エンコード変換は、次の 2 とおりの方法で制御できます。

次の 2 つのフローチャートでは、MBSTRING バッファの割り当て、送信、受信、および変換時に環境変数および ATMI がどのように使用されるかを示します。

図 3-2 MBSTRING バッファの割り当ておよび送信

MBSTRING バッファの割り当ておよび送信

図 3-3 MBSTRING バッファの受信および変換 (シート 1/2)

MBSTRING バッファの受信および変換 (シート 1/2)

図 3-3 MBSTRING バッファの受信および変換 (シート 2/2)

MBSTRING バッファの受信および変換 (シート 2/2)

MBSTRING を自己記述型にする

sendlen がゼロに設定されている場合、MBSTRING を自己記述型にすることができます。一部の Tuxedo バッファでは、ユーザがバッファの長さを指定していない場合、バッファが長さを自己決定できます。この自己記述型の動作は、アプリケーションが、Tuxedo 関数呼び出し (tpcall() など) の sendlen 引数をゼロに設定したときにトリガされます。

実装

この自己記述型の動作を実装するには、以下の操作を行います。

_mbspresend() を追加するには、Tuxedo バッファをカスタマイズするユーザがアプリケーションを再ビルドする必要があります。

安全/危険なエンコード名

TPMBENC で指定する安全または危険なエンコード名という考えは、これらのエンコードのマルチバイト文字データに NULL が埋め込まれているかどうかで決まります。_mbspresend() 関数は strlen() を使用してデータの長さを決めるので、NULL が埋め込まれていると、データの長さが不適切になり、誤ったデータ バイト数が送られてしまいます。

sendlen0_unsafe_tpmbenc のデフォルト リストには、NULL が埋め込まれている可能性がある (便宜上、大文字および小文字の) マルチバイト Unicode エンコード名があります。アプリケーション管理または性能が考慮すると、このリストを変更する必要があります。

マルチバイト文字サポートの制限

Oracle Tuxedo のマルチバイト文字サポートには、以下の制限が存在します。

マルチバイト文字エンコードでの libiconv のサポート

Oracle Tuxedo 8.1 以降のソフトウェア配布キットには、多くのエンコード文字セットとエンコードをサポートするエンコード変換ライブラリ、GNU libiconv が付属しています。マルチバイト文字エンコードの機能では、このライブラリの文字変換関数を使用して、サポートされている任意の文字エンコードから別の文字エンコードに Unicode 変換を通じて変換できます。

libiconv では、次のエンコードをサポートします。

関連項目

マルチバイト文字エンコードの詳細については、次のマニュアルを参照してください。

 


バッファのカスタマイズ

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

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

表 3-10 カスタム バッファ タイプの特性
特性
説明
バッファ タイプ
バッファ タイプの名前。8 文字以内の文字列で指定します。
バッファ サブタイプ
バッファ サブタイプの名前。16 文字以内の文字列で指定します。サブタイプは、特定のタイプのバッファに必要となる処理の違いを示すために使用されます。サブタイプ値としてワイルドカード文字 (*) を指定すると、同じ汎用ルーチンを使用して、指定されたタイプのすべてのバッファが処理されます。サブタイプが定義されているバッファは、リスト内でワイルドカードより前に置く必要があります。置かないと、処理が正常に行われません。
デフォルト サイズ
対応するバッファ タイプが割り当てまたは再割り当てされるときの最大サイズ。バッファ タイプにゼロより大きい適切な値が設定されている場合、バッファを割り当てや再割り当てする際に、バッファ サイズにゼロを指定できます。

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

表 3-11 カスタム バッファ タイプのルーチン
ルーチン
説明
バッファの初期化
新しく割り当てられた型付きバッファを初期化します。
バッファの再初期化
型付きバッファを再初期化します。このルーチンは、バッファが新しいサイズで再割り当てされたときに呼び出されます。
バッファの非初期化
型付きバッファを非初期化します。このルーチンは、型付きバッファが解放される直前に呼び出されます。
バッファの送信前処理
型付きバッファを送るための前処理を行います。このルーチンは、メッセージとして型付きバッファを別のクライアントやサーバに送信する前に呼び出されます。転送されるデータの長さが返されます。
バッファの送信後処理
型付きバッファを元の状態に戻します。このルーチンは、メッセージの送信後に呼び出されます。
バッファの受信後処理
アプリケーションで受信された型付きバッファを準備します。アプリケーション データの長さが返されます。
エンコード/デコード
バッファ タイプで必要なすべてのエンコードとデコードを行います。入力バッファと出力バッファ、およびその長さと共に、エンコードやデコードの要求がルーチンに渡されます。エンコードに使用される形式はアプリケーションで決定され、ほかのルーチンと同じように、バッファ タイプによって異なる場合があります。
ルーティング
ルーティング情報を指定します。このルーチンは、型付きバッファ、バッファのデータ長、管理者がコンフィグレーションした論理的なルーティング名、および対象サービスを指定して呼び出されます。この情報に基づいて、アプリケーションでメッセージの送信先サーバ グループが選択されるか、またはメッセージが不要であることが決定されます。
フィルタ
フィルタ情報を指定します。このルーチンは、型付きバッファに対する式の評価するときに呼び出され、合致したかどうかを返します。型付きバッファが VIEW または FML の場合、FML ブール式が使用されます。イベント ブローカは、このルーチンを使用してイベントが合致しているかどうかを評価します。
書式
型付きバッファの印字可能な文字列を指定します。

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

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

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

  1. 必要なスイッチ要素ルーチンのコードを記述します。
  2. tm_typesw に、新しいタイプとバッファ管理モジュールの名前を追加します。
  3. 新しい共有オブジェクトまたは DLL をビルドします。共有オブジェクトまたは DLL には、更新されたバッファ タイプ スイッチとそれに対応する関数が含まれていなければなりません。
  4. 新しい共有オブジェクトまたは DLL をインストールして、すべてのサーバ、クライアント、および Oracle Tuxedo システムで提供される実行可能ファイルが実行時に動的にロードされるようにします。

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

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

コード リスト 3-17 デフォルトのバッファ タイプ スイッチ
#include <stdio.h>
#include <tmtypes.h>
/* 
* バッファ タイプ スイッチの初期化
*/
struct tmtype_sw_t tm_typesw[] = {
{
"CARRAY", /* type */
"*", /* subtype */
0 /* dfltsize */
NULL, /* initbuf */
NULL, /* reinitbuf */
NULL, /* uninitbuf */
NULL, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
NULL, /* encdec */
NULL, /* route */
NULL, /* filter */
NULL, /* format */
NULL, /* presend2 */
NULL /* マルチバイト コード セット エンコード変換 */
},
{
"STRING", /* type */
"*", /* subtype */
512, /* dfltsize */
NULL, /* initbuf */
NULL, /* reinitbuf */
NULL, /* uninitbuf */
_strpresend, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
_strencdec, /* encdec */
NULL, /* route */
_sfilter, /* filter */
_sformat, /* format */
NULL, /* presend2 */
NULL /* マルチバイト コード セット エンコード変換 */
},
{
"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 */
NULL, /* presend2 */
NULL /* マルチバイト コード セット エンコード変換 */
},
{
"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 */
NULL, /* presend2 */
NULL /* マルチバイト コード セット エンコード変換 */
},
{
/* XATMI - CARRAY と同じ */
"X_OCTET", /* type */
"*", /* subtype */
0 /* dfltsize */
},
{ /* XATMI - VIEW と同じ */
{'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 */
NULL, /* presend2 */
NULL /* マルチバイト コード セット エンコード変換 */
},
{
/* XATMI - VIEW と同じ */
{'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 */
NULL, /* presend2 */
NULL /* マルチバイト コード セット エンコード変換 */
},
{
"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 */
_fpresend232, /* presend2 */
_fmbconv32 /* マルチバイト コード セット エンコード変換 */
},
{
"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 */
NULL, /* presend2 */
_vmbconv32, /* マルチバイト コード セット エンコード変換 */
},
{
"XML", /* type */
"*", /* subtype */
0, /* dfltsize */
NULL, /* initbuf */
NULL, /* reinitbuf */
NULL, /* uninitbuf */
NULL, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
NULL, /* encdec */
_xroute, /* route */
NULL, /* filter */
NULL, /* format */
NULL, /* presend2 */
NULL /* マルチバイト コード セット エンコード変換 */
},
{
"MBSTRING", /* type */
"*", /* subtype */
0, /* dfltsize */
_mbsinit, /* initbuf */
NULL, /* reinitbuf */
NULL, /* uninitbuf */
_mbspresend, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
NULL, /* encdec */
NULL, /* route */
NULL, /* filter */
NULL, /* format */
NULL, /* presend2 */
_mbsconv /* マルチバイト コード セット エンコード変換 */
},
{
""
}
};
struct tmtype_sw_t _TM_FAR *
_TMDLLENTRY
_tmtypeswaddr(void)
{
return(tm_typesw);
}

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

コード リスト 3-18 バッファ タイプ構造体
/*
* 以下の定義は、$TUXDIR/include/tmtypes.h にあります。
*/
#define TMTYPELEN ED_TYPELEN
#define TMSTYPELEN ED_STYPELEN
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));
   /* XDR エンコード/デコード関数へのポインタ */
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));
   /* 送信前、おそらくコピー生成前のバッファの処理 */
long (_TMDLLENTRY *presend2) _((char _TM_FAR *, long,
long, char _TM_FAR *, long, long _TM_FAR *));
   /* マルチバイト コード セットのエンコードの変換関数へのポインタ */
long (_TMDLLENTRY *mbconv) _((char _TM_FAR *, long,
char _TM_FAR *, char _TM_FAR *, long, long _TM_FAR *));
   /* この領域は将来の拡張のために予約されています。 */
void (_TMDLLENTRY *reserved[8]) _((void));
};
/*
* アプリケーション バッファ タイプのスイッチ ポインタ
* テーブルへのアクセス時には常にこのポインタを使用します。
*/
extern struct tmtype_sw_t *tm_typeswp;

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

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

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

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

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

スイッチ要素ルーチンのコーディング

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

コード リスト 3-19 送信前処理スイッチ要素のセマンティクス
long
presend(ptr, dlen, mdlen)
char *ptr;

long dlen, mdlen;

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

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

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

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

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

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

コード リスト 3-20 新しいタイプのバッファ スイッチへの追加
#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 2003 プラットフォームでは、「共有オブジェクト」ではなく「動的リンク ライブラリ」と呼ばれています。この 3 つの用語が示す機能は同じなので、ここでは「共有オブジェクト」を使用します。

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

  1. tm_typesw への新しいバッファ タイプの追加」の説明に従って、$TUXDIR/lib/tmtypesw.c をコピーして変更します。関数を追加する場合は、それらの関数を tmtypesw.c に記述するか、別の C ソース ファイルに記述します。
  2. 共有オブジェクトに必要なフラグを設定し、tmtypesw.c をコンパイルします。
  3. すべてのオブジェクト ファイルをリンクして、共有オブジェクトを生成します。
  4. libbuft.so.71 をカレント ディレクトリから別のディレクトリにコピーします。コピー先のディレクトリとしては、アプリケーションが libbuft.so.71 を認識でき、Oracle Tuxedo システムで提供されるデフォルトの共有オブジェクトより先に libbuft.so.71 が処理されるディレクトリを選択します。$APPDIR または $TUXDIR/lib ディレクトリ、または $TUXDIR/bin (Windows 2003 プラットフォームの場合) のいずれかを使用することをお勧めします。

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

表 3-12 バッファ タイプ スイッチ共有オブジェクトの 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 を変更した場合、次のコード リストに示すコマンドを使用して、変更後のバッファ タイプ スイッチをアプリケーションから使用できるようにします。

コード リスト 3-21 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 が異なることが Oracle Tuxedo システムによって検出された場合だけです。


  ページの先頭       前  次