ここでは、次の内容について説明します。
Oracle Tuxedo TxRPC は、『DCE: REMOTE PROCEDURE CALL』(Doc Code:P312 ISBN 1-872630-95-2) の第 3 章「Interface Definition Language」で説明されている IDL 文法と関連機能をサポートしています。この本は以下から入手できます。
X/OPEN Company Ltd (Publications)
P O Box 109
Penn
High Wycombe
Bucks HP10 8NP
United Kingdom
電話 : +44 (0) 494 813844
FAX : +44 (0) 494 814989
X/OPEN ドキュメントは、Oracle Tuxedo 製品が準拠し、その言語および規則の原典とするものです。X/OPEN TxRPC IDL-only インタフェースがサポートされていることに注意してください。DCE バインドとランタイムに関するドキュメントの一部は適用されません。X/OPEN ドキュメントは OSF DCE AES/RPC ドキュメントを基本としています。チュートリアル、プログラマーズ ガイドとして入手可能な文献は多数ありますが、ほとんどのものには最新の機能は記載されていません。OSF から入手できるプログラマーズ ガイドとして、Prentice-Hall の『OSF DCE Application Development Guide』(Englewood Cliffs, New Jersey, 07632) があります。
『X/OPEN Preliminary Specification for TxRPC Communication Application Programming Interface』(TxRPC 通信アプリケーション プログラミング インタフェースのための X/OPEN 予備仕様) もまた X/OPEN から入手できます (上記を参照)。TxRPC は、RPC 用のトランザクション サポートをオリジナルの X/OPEN RPC インタフェースに追加しています。
汎用一意識別子 (UUID) はインタフェースを一意に識別するために使用します。uuidgen コマンドを実行して UUID を生成します。出力は次のようになります。
$ uuidgen -i > simp.idl
$ cat simp.idl
[uuid(816A4780-A76B-110F-9B3F-930269220000)]
interface INTERFACE
{
}
次にこのテンプレートを使用して、型定義、定数、およびオペレーションを追加するアプリケーション用の IDL 入力ファイルを作成します。
Oracle Tuxedo と DCE の両方の uuidgen(1) コマンドを利用できる場合は、DCE コマンドでテンプレートを生成する必要があります。DCE バージョンでは通常、以下で説明するとおり、ノード アドレスを取得するためにマシン固有の手法を採用しています。
Oracle Tuxedo システムの uuidgen コマンドは、-s オプション (初期化された C 構造体として UUID 文字列を生成する) と、-t オプション (以前の形式の UUID 文字列を新規形式に変換する) をサポートしていない点を除いて、DCE コマンドと同じです。インタフェースの詳細については uuidgen(1) のリファレンス ページを参照してください。
uuidgen コマンドは、ISO/IEC 8802-3 (ANSI/IEEE 802.3) に記載されているように 48 ビット ノード アドレスを要求します。プラットフォームに依存せずにこの値を求める方法は存在しません。また一部のマシン (ワークステーションなど) ではまったく利用できないこともあります。Oracle Tuxedo システムの uuidgen コマンドでは、次の手法が使用されています。
NADDR 環境変数が num.num.num.num.num.num の形式の値で設定されている場合、インターネット スタイルのアドレスが採用され、48 ビットのノード アドレスに変換されます。ここで num は 0 と 255 を含む、0 から 255 までの値です。これにより 8802-3 ノード アドレスの使用法に準拠できます。また、このアドレスにアクセスできないユーザも、インターネット アドレス (8802-3 アドレスと同じではない) 等の別の値を利用できるようになります。インターネット アドレスを使用している場合、インターネット アドレスは 32 ビット アドレスなので、最後の num.num は 0.0 とします。
NADDR 環境変数が設定されておらず、WSNADDR 環境変数が 0xnnnnnnnnnnnnnnnn 形式の値に設定されている場合、ワークステーションで使用されるような、16 進数のネットワーク アドレスが採用されることになります。これは 8802-3 アドレスではなく、また最後の 16 ビットはゼロとして処理されることに注意してください。
NADDR 環境変数と WSNADDR 環境変数のいずれも設定されていない場合には、(また Windows でない場合)、そのマシンの uname を用いて /etc/hosts 内のマシン エントリと照合し、インターネット スタイルのアドレスを取得します。
上記のいずれにも当てはまらない場合、警告が表示され、アドレス 00.00.00.00.00.00 が採用されます。これは、ユニークな UUID を生成できる可能性が低くなるので望ましい方法ではありません。
IDL コンパイラは IDL 文法を認識して、入力に基づいてスタブ関数を生成します。文法とそのセマンティクスは、本章前半に記載した X/OPEN リファレンスと OSF/DCE リファレンスの両方に詳しく説明されています。次の項目で説明するいくつかの変更を加えることで文法はそのまま認識されます。
次に X/OPEN TxRPC 仕様に定義されている基本 X/OPEN RPC 仕様に対する変更点を示します。
TxRPC 仕様からの最も重要な拡張点は、IDL ファイルのインタフェースとオペレーション属性に [transaction_optional] と [transaction_mandatory] 属性を追加した点です。[transaction_optional] は、トランザクション内で RPC を実行する場合、トランザクションの一部としてリモート サービスが実行されることを示します。[transaction_mandatory] 属性ではトランザクション内で RPC が実行される必要があります。これらの属性の指定がなければ、リモート サービスはクライアントのトランザクションの一部ではありません。
X/OPEN TxRPC IDL-only では型と属性のバインドは必須ではありません。属性のバインドには、[handle]、[endpoint]、[auto_handle]、[implicit_handle]、および [explicit_handle] があります。これらの属性は tidl(1) によって認識されますがサポートされていません (無視されます)。handle_t 型に対しても特別な処理は行われません。ほかの定義済みの型と同様に受け渡され、ハンドルとしては処理されません。
X/OPEN TxRPC IDL-only ではパイプは必須ではありません。tidl は [local] モードでしかパイプをサポートしません。つまり、パイプはヘッダ ファイル用として指定できますが、スタブ生成用としては指定できません。
X/OPEN TxRPC IDL-only では [idempotent]、[maybe]、および [broadcast] 属性は必須ではありません。tidl(1) はこれらの属性を無視します。
次に X/OPEN RPC 仕様に対する強化を示します。多くの場合、言語は C 言語により密接に従うように拡張されており、ANSI C から IDL プロトタイプに変換することにより、既存インタフェースの移植を簡素化しています。
X/OPEN 仕様では、文字定数と文字列は移植可能なセット、つまりスペース (0x20) からティルダ (0x7e) までに制限されています。OSF DCE RPC では、文字セット (0x01 から 0xff まで) 内のその他の文字の使用も認められています。
C と同様、以下の演算子は区切り文字として扱われます。
││ && ? │ & _ == != = << >> <= >= < > + - % ! ~
つまり、これらのトークンの 1 つが先行するまたは後続する場合は、識別子または数字の前または後に空白を入れる必要はないということです。IDL 仕様では 'a=b+3' は認められず、'a = b + 3' のように空白を入れる必要があります。これは OSF DCE IDL コンパイラの動作によるものと思われます。
公開されている X/OPEN 仕様では、フィールド名とパラメータ名に型名を使用できないという制約があります。この制約により、すべての名前を単一のネームスペースに置くことができます。この制約は C、C++ または OSF IDL コンパイラの仕様と整合性がないので、強制するものではありません。
X/OPEN 仕様は、パラメータまたは関数の結果として匿名の列挙を認めておらず、またポインタの対象として匿名構造体またはユニオンを認めていません。これらについては OSF DCE IDL コンパイラでは認められています。これらの制約は強制されません。インタフェース名およびバージョンに基づく名前は、マーシャリング中に使用するために生成されます。
C と同様に、列挙値 (定数) は整数定数式で使用できます。これは DCE IDL コンパイラの動作によるものと思われます。
現時点の X/OPEN RPC 仕様の定義では、次のようにオペレーション宣言子の前にポインタを置くことは文法上認められません。
long *op(void);
また、構造体またはユニオンを返すことも認めていません。すべてを定義済みの型に隠ぺいできるという点で正しいと考えられますが、DCE IDL コンパイラと、もちろん C コンパイラはより豊富なオペレーションを返すことを認めています。サポートされている文法は以下のようになります。
[operation_attributes] <type_spec> <declarator>
この場合の <declarator> は、<function_declarator> を含む必要があります。<function_declarator> が存在しない場合、変数は宣言されますが、結果としてエラーになります。オペレーションの配列または配列を返すオペレーションを宣言することは共にこの文法で認められていて、宣言としては認識されますが、エラーが通知されます。
IDL <type_declaration> が宣言子のリストを取るように、<ACS_type_declaration> は <ACS_named_type> 値を取ります。これは DCE IDL コンパイラの動作によるものと思われます。
フィールド操作言語 (FML:Field Manipulation Language) を使用して作成、操作されるフィールド化バッファは多くの Oracle Tuxedo アプリケーションの不可欠の部分になっています。フィールド化バッファは、IDL では新しい基本型としてサポートされます。フィールド化バッファは、16 ビット バッファについてはキーワード FBFR で、32 ビット バッファはキーワード FBFR32 で示され、ポインタとして定義される必要があります (たとえば FBFR * または FBFR32 *)。フィールド化バッファは typedef で基本型として定義することはできません。フィールド化バッファは、構造体のフィールドで、さらにパラメータとして使用できます。フィールド化バッファは配列またはポインタ (完全ポインタまたは参照ポインタのいずれか) の基本型として使用できますが、フィールド化バッファの整合配列と可変配列はサポートされません。
OSF IDL コンパイラでは、AES 仕様または X/OPEN RPC 仕様にドキュメント化されていない制約がいくつか存在します。Oracle Tuxedo の IDL コンパイラではこれらの制約が強制されます。
[transmit_as()] で使用する転送型には [represent_as] 属性を設定できません。
ユニオン アームを [ref] ポインタにしたり、ユニオン アームに [ref] ポインタを含めることはできません。
整合配列と可変配列の両方あるいはいずれか一方が構造体に存在する場合は、配列サイズの属性変数はポインタにはできません。つまりポインタではなく、構造体内の整数要素である必要があります。
X/OPEN RPC 仕様に対して Oracle Tuxedo の 4 つの拡張機能が追加されており、これらは仕様をより C 言語に近づける一方で、OSF DCE IDL コンパイラではサポートされないために IDL ファイルの移植性に制限を加えることになります。
ANSI C と同様に、文字列連結がサポートされます。つまり、
const char *str = "abc" "def";
は、次と同じように扱われます。
const char *str = "abcdef";
エスケープ文字を使用した改行を文字列定数内で用いることができます。つまり、
const char *str = "abc\ def";
は、次と同じように扱われます。
const char *str = "abcdef";
列挙値はユニオン ケースでも使用でき、整数として扱われます。C と同様に自動的に変換されます。
各 <union_case_label> の型を <switch_type_spec> によって指定する必要があるという制約は設けていません。代わりに、C の switch ステートメントの case ステートメントで行われるような型の強制変換が行われます。
以下の 7 つの機能は tidl コンパイラではサポートされていません。
移行属性 [v1_struct]、[v1_enum]、[v1_string]、[v1_array] は認識されますが、サポートされていません。これらの属性は OSF IDL 仕様にはありますが、X/OPEN 仕様にはありません。
OSF/DCE と同様に [local] モードでのみ OSF/DCE ドキュメントに定義された関数ポインタがサポートされます。
クライアントとサーバ間ではインタフェースのマイナー バージョンまで完全に一致する必要があります。X/OPEN RPC 仕様では、サーバのマイナー バージョンがクライアントのマイナー バージョンよりも大きいか等しい場合も許可しています。
32 ビット長のマシンでは、整数リテラル値は -2**31 から 2**31 の範囲に制限されています。2**31+1 から 2**32-1 の範囲の unsigned long 整数値はサポートされません。これは DCE IDL コンパイラの動作によるものと思われます。
コンテキスト ハンドルは [local] モードだけでサポートされます。状態をまたがるオペレーションを管理するためにコンテキスト ハンドルを使用して、インタフェースを記述することはできません。
[out-of-line] ACS 属性は無視されます。この機能は、たとえば OSF IDL コンパイラを使用する異なる実装間での相互運用をサポートするという点では定義されていません。
[heap] ACS 属性は無視されます。
IDL コンパイラ用のインタフェースは、X/OPEN 仕様では指定されていません。
DCE アプリケーションの移植性を考慮し、Oracle Tuxedo システムの IDL コンパイラのインタフェースは DCE IDL コンパイラと同様ですが、次のような例外があります。
コマンド名は idl の代わりに tidl を用います。同じ環境に両方のコンパイラが存在する場合でも、コンパイラの識別がアプリケーションから容易に行えます。
-bug オプションは、旧バージョンのソフトウェアとの相互運用のために、誤動作を起こさせます。このオプションは無効です。-no_bug オプションも無効です。
-space_opt オプションは無視されます。このオプションは、コード領域の最適化を行います。領域は常に最適化されます。
新しいオプション -use_const がサポートされています。-use_const は、定数定義用の #define ステートメントの代わりに ANSI C const ステートメントを生成します。このオプションにより、IDL ファイル内で定義された定数が C プリプロセッサ定義を使用するファイル内の別の定数名と競合するというやっかいな問題を回避できます。このオプションにより、C の定数として定義されるときに、これらの定数は別のネームスペースに正しく配置されます。本機能を使うと、IDL ファイルの移植性が制限されます。
デフォルトでは、/lib/cpp、/usr/ccs/lib/cpp、または /usr/lib/cpp のいずれかのコマンドを使用して、入力 IDL ファイルと入力 ACF ファイルのプリプロセッサ処理を行ないます。3 つのプリプロセッサのうち最初に見つかったものを使用します。
デフォルトでは、IDL コンパイラは入力 IDL ファイルを受け取り、クライアントとサーバ スタブのオブジェクト ファイルを生成します。-keep c_source オプションは C ソース ファイルだけを生成し、-keep all オプションは C ソース ファイルとオブジェクト ファイルの両方を保持します。「アプリケーション例」で示したサンプル RPC アプリケーションでは、-keep object オプションを使用してオブジェクト ファイルを生成しています。
デフォルトでは、tidl は最大 50 個までのエラーを表示します。エラー数が 50 個を超えている場合に、すべてのエラーを表示するときは、-error all オプションを指定します。エラー出力は stderr に送られます。
その他使用可能なオプションの詳細については、『Tuxedo コマンド リファレンス』の tidl(1) を参照してください。