Building An Example RPC Application
The following example shows the commands needed to build a RPC application,
a rather simple file server called "Filer". VAX/VMS is used here for
illustration: There are further examples under the later sections
which deal with each environment.
Suppose we have a program called MYPROG.FOR written in FORTRAN and
running on a VAX under VMS. This needs to call procedures in a module
called FILER written in Pascal and running on an M68020 under MoniCa.
The interface between the two is described in RPCL in the file FILER.RPC
. Because this is an example we have deliberatly chosen Fortran for
the main program and Pascal for the server to show a mixed language
application: however, the modules could as well both have been written
in the same language, and run on the same type of machine.
First of all we compile the main program using the native FORTRAN
compiler, generating the file MYPROG.OBJ, and we compile the server
module using the cross Pascal compiler, generating the file FILER.CUF.
We then generate the stub code for each system using the RPC Compiler:
$ RPC FILER.RPC /SCERNCROSS
$ RPCC FILER.RPC /CFORTRAN=CLIFILER.FOR
These commands will produce (if no errors are found) the files:
SERFILER.CUF The server stub, in M680x0 object format
FILER.EXT The Pascal declaration file
CLIFILER.FOR The client stub in FORTRAN
The client stub is compiled:
$ FORTRAN CLIFILER
Next, we link together the VAX image:
$ LINK MYPROG, CLIFILER, rpc_lib/OPT
We now have an executable file, MYPROG.EXE, which, when run, will
call the remote version of FILER. To link the M68k object modules
together, we have to first concatenate them into one file, then use
CUFLINK, then format the result with UNIPUSH:
$ COPY FILER.CUF, SERFILER.CUF FILER.CCU
$ CUFLINK FILER.CCU, rpc_lib68, FILER, -
MYLOP, MYOPT, MYLMP
$ UNIPUSH FILER
The result is FILER.ABS, a Motorola "S&hyphen.format" loadable file
which, when run, will provide the service required by MYPROG.EXE.
(The use of cross software under VAX/VMS, and the significance of
the LOP, OPT and LMP files, is described in and its references). The
name rpc_lib68 is a logical name. The actual file used to satisfy
entry points into the RPC system will depend on the target M680x0
system being used, typically the MONICA.ROM file. (See also: Running
this example VAX-VAX over Decnet)
Stubs in C
This example is equivalent to the example above, but we assume that
the client and/or server routines will be written in C. (The client
stub should be produced in C if the client module is in C, and the
server module should be produced in C if the server module is written
in C. This does not stop a C client talking to a FORTRAN server, for
instance, as the communication format used between the stubs is the
same in all cases)
The RPCC command is used. To make the VMS client, the commands would
be
$ RPCC FILER.RPC /CGENERICC=CLIFILER.C/BYVALUE ! Make CLIFILER.C
$ CC/INC=RPC_INC/DEFINE=VAXVMS CLIFILER ! Make CLIFILER.OBJ
$ LINK MYPROG, CLIFILER, rpc_lib/OPT ! MAKE MYPROG.EXE
and to make ther server,
$ RPCC FILER.RPC /SGENERICC=SERFILER.C/BYVALUE ! Make SERFILER.C
$ CC/INC=RPC_INC/DEFINE=VAXVMS SERFILER ! Make SERFILER.OBJ
$ LINK FILER, SERFILER, rpc_lib/OPT ! Make FILER.EXE
In this case, FILER must contain, apart from the server subroutines,
a small main program to attach the server stub to the run-time system,
and call the server loop. (See Server Programs )
Explicit Post Processing of Pascal stubs
(This section is only relevant to users making stubs in Pascal, and
who wish to modify them by hand). The RPC command used above produces
object modules via intermediate files generated in Pascal. In some
cases, howver, one may wish to invoke the RPC compiler only to produce
source versions of the stub code, which can then be modified before
compilation. In this case, the RPCC (two C's) command is used, and
the compiler produces the source files: in our example , these would
be, by default,
CLIFILER.RPC The client stub, in M68020 Pascal
SERFILER.RPC The server stub, in VAX/VMS Pascal
FILER.EXT The Pascal declaration file (as before).
The .RPC files must be put through the INCLUDE preprocessor to make
pascal files, and these must in turn be compiled using a suitable
pascal compiler. In the example above, the operations required are
as follows: We compile the client stub using the INCLUDE preprocessor,
and the native VAX Pascal compiler.
$ INCLUDE CLIFILER.RPC CLIFILER.PAS +VAXVMS
$ PASCAL CLIFILER
This generates the object file CLIFILER.OBJ. (Theer is also an optional
+ALIGN keyword, (See index "ALIGN") as discussed in a later chapter,
but its inclusion is not recommended). on it. (Note the upper case
for all keywords). To make the M68k code, we compile the server stub,
SERFILER.RPC, using the Cross PASCAL compiler and the INCLUDE preprocessor:
$ INCLUDE SERFILER.RPC SERFILER.PAS CERNCROSS
$ NEWP68K SERFILER
generating the object file SERFILER.CUF for the M68k. The INCLUDE
program is part of the CERN cross software suite for the M680x0 processors,
and is described in outline in .
To produce the same thing in C for unix and under unix, the commands
would have been, with $(RPCLIB) replaced by the pathname of the RPC
library librpc.a:
rpcc -cgenericc=clifiler.c -byvalue filer.rpc
cc -o myprog myprog.c clifiler.c $(RPCLIB)
and to make ther server,
rpcc -sgenericc=serfiler.c -byvalue filer.rpc
cc -o filer filer.c serfiler.c $(RPCLIB)
Unix cross software
If the development of the M68k part were to be done under Berkley
Unix or Ultrix, the commands would have been similar to those used
above, with explicit post processing of the stubs:
rpcc filer.rpc -ccerncross -svaxvms
include CERNCROSS < serfiler.rpc > serfiler.p
pasc68k serfiler
cat filer.cuf clifiler.cuf > myprog.ccu
cuflink myprog
unipush myprog
The file CERNCROSS.DFS is not needed in this case, as the keywords
are command line parameters. This will similarly produce the file
'myprog.abs'. Note that, whereas on the client side the user program
is a main program, on the server side the user code is just a called
module. A main program module is, however, necessary on the server
side, to call the RPC system and ask it to service future requests.
In the example above it is assumed that this is part of FILER.CUF.
This module is normally quite simple, and is discussed elsewhere .