ONC+ 開発ガイド

ディスパッチテーブル

RPC パッケージで使用するディスパッチテーブルにプログラムからアクセスしたい場合があります。たとえば、サーバーディスパッチルーチンで権限を調べてからサービスルーチンを呼び出したり、クライアントライブラリで記憶管理や XDR データ変換の詳細を扱う場合です。

-T オプションを指定して rpcgen を起動すると、プロトコル記述ファイル proto.x で定義した各プログラムごとの RPC ディスパッチテーブルがファイル proto_tbl.i に出力されます。接尾辞.i は index を表します。-t オプションを指定して rpcgen を起動した場合は、ヘッダーファイルだけが生成されます。rpcgen を起動するときは、C 形式モード (-N オプション) と同時に -T または -t フラグを指定することはできません。

ディスパッチテーブルの各エントリは struct rpcgen_table で、この構造体はヘッダーファイル proto.h で次のように定義されています。

struct rpcgen_table {
  char *(*proc)();
  xdrproc_t xdr_arg;
  unsigned len_arg;
  xdrproc_t xdr_res;
  xdrproc_t len_res
};

ここでの定義は、次のとおりです。

proc      サービスルーチンへのポインタ
 xdr_arg   入力 (引数) の xdr ルーチンへのポインタ
 len_arg   入力引数の長さ (バイト数)
xdr_res   出力 (結果) の xdr ルーチンへのポインタ
len_res    出力結果の長さ (バイト数)

サンプルプログラム dir.x のディスパッチテーブル dirprog_1_table は、手続き番号がインデックスになっています。変数 dirprog_1_nproc には、テーブル内のエントリ数が入っています。

ディスパッチテーブルから手続きを探し出すルーチン find_proc() を次に示します。


例 3-27 ディスパッチテーブルの使用方法

struct rpcgen_table *
find_proc(proc)
  rpcproc_t proc;
{
  if (proc >= dirprog_1_nproc)
       /* error */
  else
  return (&dirprog_1_table[proc]);
} 

ディスパッチテーブル内の各エントリは対応するサービスルーチンへのポインタです。ところが、サービスルーチンは一般にクライアント側のコードでは定義されていません。未解決の外部参照を起こさないため、また、ディスパッチテーブルに対するソースファイルを 1 つだけ要求にするために RPCGEN_ACTION(proc_ver) で、rpcgen サービスルーチン の初期化を行います。

これを使用して、クライアント側とサーバー側に同一のディスパッチテーブルを持たせることができます。クライアント側プログラムをコンパイルするときは、次の define 文を使用します。

#define RPCGEN_ACTION(routine) 0

サーバー側プログラムを作成するときは、次の define 文を使用します。

#define RPCGEN_ACTION(routine)routine