ONC+ 開発ガイド

rpcgen の 64 ビットの場合の考慮事項

例 3-27 では、proc は タイプ rpcproc_t として宣言されていることに注意してください。正式には、RPC のプログラム、バージョン、手続き、およびポートは、タイプ u_long として宣言されていました。32 ビットマシン上では、u_long の量は 4 バイト (int として) で、64 ビットシステム上では u_long の量は 8 バイトになります。RPC のプログラム、バージョン、手続き、およびポートを宣言できる場合には必ず、u_longlong の代わりに Solaris 7 で導入されたデータタイプ rpcprog_trpcvers_trpc_proc_trpcport_t を使用する必要があります。これらの新しいタイプを使用すると、32 ビットシステムとの下位互換性があるからです。つまり、この新しいデータタイプによって、rpcgen を実行するシステムに関係なく、4 バイトの量が保証されます。プログラム、バージョン、および手続きの u_long バージョンを使用する rpcgen プログラムを引き続き実行すると、32 ビットマシンと 64 ビットマシンでは、異なる結果になる場合があります。そのため、これらを該当する新しいデータタイプに置き換えることをお勧めします。実際、可能な限り longu_long の使用は避けた方が賢明です (この後の注を参照)。

Solaris 7 以降の rpcgen を起動する場合、rpcgen によって作成されたソースファイルには XDR ルーチンが組み込まれていて、このソースファイルは、そのコードを 32 ビットマシンと 64 ビットマシン上のどちらで実行するかによって、異なるインラインマクロが使用されます。特に、IXDR_GETLONG()IXDR_PUTLONG() の代わりに、IXDR_GET_INT32()IXDR_PUT_INT32() マクロが使用されます。たとえば、rpcgen ソースファイル foo.x に以下のコードが組み込まれている場合を考えます。

struct foo {
        char      c;
        int       i1;
        int       i2;
        int       i3;
        long      l;
        short     s;
};
この場合生成されるファイル foo_xdr.c ファイルでは、次のように適切なインラインマクロが使用されているかどうか確認されます。
#if defined(_LP64) || defined(_KERNEL)
        register int *buf;
#else
        register long *buf;
#endif
 
. . .
 
#if defined(_LP64) || defined(_KERNEL)
                        IXDR_PUT_INT32(buf, objp->i1);
                        IXDR_PUT_INT32(buf, objp->i2);
                        IXDR_PUT_INT32(buf, objp->i3);
                        IXDR_PUT_INT32(buf, objp->l);
                        IXDR_PUT_SHORT(buf, objp->s);
#else
                        IXDR_PUT_LONG(buf, objp->i1);
                        IXDR_PUT_LONG(buf, objp->i2);
                        IXDR_PUT_LONG(buf, objp->i3);
                        IXDR_PUT_LONG(buf, objp->l);
                        IXDR_PUT_SHORT(buf, objp->s);
#endif
このコードにより、 bufint または long のどちらかになるように宣言されますが、これはマシンが 64 ビットであるか、または 32 ビットであるかによって決まるということに注意してください。


注 -

現在は、RPC を通じて転送されるデータタイプのサイズは、4 バイトの量 (32 ビット) に制限されています。8 バイトの long は、アプリケーションが 64 ビットのアーキテクチャを最大限に使用できるようにする場合に提供されます。ただし、プログラマは、int のために long や、x_putlong() などの long を使用する関数の使用は、可能な限り避ける必要があります。上述したように、RPC プログラム、バージョン、手続きおよびポートにはそれぞれ専用のタイプがあります。 それは、データ値が INT32_MININT32_MAX の間にない場合、xdr_long() は失敗し、また、IXDR_GET_LONG()IXDR_PUT_LONG() などのインラインマクロが使用されると、そのデータは切り捨てられるからです (u_long の場合も同様) 。xdr_long(3NSL) のマニュアルページも参照してください。