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_table には、テーブル内のエントリ数が入っています。

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

struct rpcgen_table *
find_proc(proc)
   u_long proc;
{
   if (proc >= dirprog_1_nproc)
       /* エラー */
   else
      return (&dirprog_1_table[proc]);
}

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

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

#define RPCGEN_ACTION(routine) 0

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

#define RPCGEN_ACTION(routine)routine