Sophie

Sophie

distrib > Mandriva > 8.2 > i586 > media > contrib > by-pkgid > 211238da6d926d1ca4390483bb29f586 > files > 58

coda-doc-5.2.0-4mdk.noarch.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
 <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
 <TITLE> RPC2 User Guide and Reference Manual: The RP2Gen Stub Generator</TITLE>
 <LINK HREF="rpc2_manual-4.html" REL=next>
 <LINK HREF="rpc2_manual-2.html" REL=previous>
 <LINK HREF="rpc2_manual.html#toc3" REL=contents>
</HEAD>
<BODY>
<A HREF="rpc2_manual-4.html">Next</A>
<A HREF="rpc2_manual-2.html">Previous</A>
<A HREF="rpc2_manual.html#toc3">Contents</A>
<HR>
<H2><A NAME="s3">3. The RP2Gen Stub Generator</A></H2>

<P>
<A NAME="RP2GenChapter"></A> <P>
<H2><A NAME="ss3.1">3.1 Introduction</A>
</H2>

<P><B>RP2GEN</B> takes a description of a procedure call interface and generates
stubs to use the RPC2 package, making the interface available on remote
hosts.  RP2GEN is designed to work with a number of different languages (C, FORTRAN 77, PASCAL), however, only the C interface is currently
implemented.
<P>RP2GEN also defines a set of external data representations for RPC types. 
These representations are defined at the end of this document in the
section entitled <B>External Data Representations.</B>  Any program wishing
to communicate with a remote program using the RP2GEN semantics must
obey these representation standards.
<P>
<H2><A NAME="ss3.2">3.2 Usage</A>
</H2>

<P>RP2GEN is invoked as follows:
<BLOCKQUOTE><CODE>
rp2gen <EM>file</EM>
</CODE></BLOCKQUOTE>
<P>
<P><EM>File</EM> is the file containing the description of the interface.  Normally,
these files have the extension <EM>.rpc2</EM>.  RPGen creates three files
named: <EM>base</EM>.client.c; <EM>base</EM>.server.c; and <EM>base</EM>.h,
where <EM>base</EM> is the name of the file without the extension and the
pathname prefix.
Thus:
<BLOCKQUOTE><CODE>
rp2gen <EM>samoan.rpc2</EM>
</CODE></BLOCKQUOTE>

would yield the files: <EM>samoan</EM>.client.c; <EM> samoan</EM>.server.c; and <EM>samoan</EM>.h.
<P>A person wanting to provide a package remotely writes his package with
a normal interface.  The client programmer writes his code to make normal
calls on the interface.  Then the client program is linked with:
<BLOCKQUOTE><CODE>
ld ... base.client.o /usr/andrew/lib/librpc2.a ...
</CODE></BLOCKQUOTE>

and the server program with
<BLOCKQUOTE><CODE>
ld ... base.server.o /usr/andrew/lib/librpc2.a ...
</CODE></BLOCKQUOTE>
<P>The server module provides a routine, the <EM>ExecuteRequest </EM>routine,
that will decode the parameters of the request and make an appropriate
call on the interface.  (The routine is described below in the language
interface sections.)  The client module translates calls on the interface
to messages that are sent via the RPC2 package.  The<CODE> .h</CODE> file contains 
type definitions that RP2GEN generated from the type definitions in
the input file, and definitions for the op-codes used by RP2GEN.  This
file, which is automatically included in the server and client files,
may be included by any other module that needs access to these types.
<P>
<H2><A NAME="ss3.3">3.3 Format of the Description File</A>
</H2>

<P>In the syntax of a description file below, non-terminals are represented
by <EM>italic</EM> names and literals are represented by <B>bold</B> strings.
<P>
<CENTER><TABLE BORDER><TR><TD>
<BR>
file ::= </TD><TD> prefixes header_line default_timeout decl_or_proc_list</TD></TR><TR><TD>
prefixes ::= </TD><TD> empty | prefix | prefix prefix</TD></TR><TR><TD>
prefix ::= </TD><TD> <B>Server Prefix</B> string <B>;</B> | <B>Client Prefix</B> string <B>;</B></TD></TR><TR><TD>
header_line ::= </TD><TD> <B>Subsystem</B> subsystem_name <B>;</B></TD></TR><TR><TD>
subsystem_name ::= </TD><TD> string</TD></TR><TR><TD>
string ::= </TD><TD> <B>"</B> zero_or_more_ascii_chars <B>"</B></TD></TR><TR><TD>
default_timeout ::= </TD><TD> <B>Timeout</B> <B>(</B> id_number <B>) ;</B> | empty</TD></TR><TR><TD>
decl_or_proc_list ::= </TD><TD> decl_or_proc | decl_or_proc decl_or_proc_list</TD></TR><TR><TD>
decl_or_proc ::= </TD><TD> include | define | typedef | procedure_description</TD></TR><TR><TD>
include ::= </TD><TD> <B>#include </B> file_name <B></B></TD></TR><TR><TD>
define ::= </TD><TD> <B>#define</B> identifier number</TD></TR><TR><TD>
typedef ::= </TD><TD> <B>typedef</B> rpc2_type identifier array_spec <B>;</B></TD></TR><TR><TD>
rpc2_type ::= </TD><TD> type_name | rpc2_struct | rpc2_enum</TD></TR><TR><TD>
type_name ::= </TD><TD> <B>RPC2_Integer </B> | <B>RPC2_Unsigned </B> | <B>RPC2_Byte </B> | <B>RPC2_String </B> | <B>RPC2_CountedBS </B> | <B>RPC2_BoundedBS </B> | <B>SE_Descriptor</B> | <B>RPC2_EncryptionKey </B> | identifier</TD></TR><TR><TD>
rpc2_struct ::= </TD><TD> <B>RPC2_Struct {</B> field_list <B>}</B></TD></TR><TR><TD>
field_list ::= </TD><TD> field | field field_list</TD></TR><TR><TD>
field ::= </TD><TD> type_name identifier_list <B>;</B></TD></TR><TR><TD>
identifier_list ::= </TD><TD> identifier | identifier <B>,</B> identifier_list</TD></TR><TR><TD>
rpc2_enum ::= </TD><TD> <B>RPC2_Enum {</B> enum_list <B>}</B></TD></TR><TR><TD>
enum_list ::= </TD><TD> enum <B>,</B> enum_list | enum</TD></TR><TR><TD>
enum ::= </TD><TD> identifier <B>=</B> number</TD></TR><TR><TD>
array_spec ::= </TD><TD> empty | <B>[</B> id_number<B>]</B></TD></TR><TR><TD>
id_number ::= </TD><TD> number | identifier</TD></TR><TR><TD>
procedure_description ::= </TD><TD> proc_name <B>(</B> formal_list <B>)</B></TD></TR><TR><TD>
</TD><TD>timeout_override new_connection <B>;</B></TD></TR><TR><TD>
proc_name ::= </TD><TD> identifier</TD></TR><TR><TD>
formal_list ::= </TD><TD> empty | formal_parameter | formal_parameter <B>,</B> formal_list</TD></TR><TR><TD>
formal_parameter ::= </TD><TD> usage type_name parameter_name</TD></TR><TR><TD>
usage ::= </TD><TD> <B>IN</B> | <B>OUT</B> | <B>IN OUT</B></TD></TR><TR><TD>
parameter_name ::= </TD><TD> identifier</TD></TR><TR><TD>
timeout_override ::= </TD><TD> <B>Timeout</B> <B>(</B> id_number<B>)</B> | empty</TD></TR><TR><TD>
new_connection ::= </TD><TD> <B>NEW_CONNECTION</B> | empty</TD></TR><TR><TD>
empty ::= </TD><TD>

</TD></TR></TABLE></CENTER>
<P>In addition to the syntax above, text enclosed in /* and */
is treated as a comment and ignored.  Appearances of an include statement
will be replaced by the contents of the specified file.
All numbers
are in decimal and may be preceded by a single hyphen:  <B>-</B>, character.
Identifiers
follow C syntax except that the underline character: <B>_</B>, may not
begin an identifier. (Note that a particular language interface defines
what identifiers may actually be used in various contexts.)
<P>The following are reserved words in RP2GEN: <B>server</B>, <B>client</B>,
<B>prefix</B>, <B>subsystem</B>, <B>timeout</B>, <B>typedef</B>, <B>rpc2_struct</B>, <B>rpc2_enum</B>,
<B>in</B> and <B>out</B>.  Case is ignored for reserved words, so that, for
example, <B>subsystem</B> may be spelled as <B>SubSystem</B> if desired. 
Case is not ignored, however, for identifiers.  Note that the predefined
type names (RPC2_Integer , RPC2_Byte , etc.) are identifiers and must
be written exactly as given above.
<P>The <EM>prefixes</EM> may be used to cause the names of the procedures in
the interface to be prefixed with a unique character string.  The line:
<P>
<BLOCKQUOTE><CODE>
Server Prefix "test";
</CODE></BLOCKQUOTE>
<P>will cause the server file to assume that the name of the server interface
procedure <EM>name</EM> is test_<EM>name</EM>.  Likewise, the statement:
<P>
<BLOCKQUOTE><CODE>
  
Client Prefix "real";
</CODE></BLOCKQUOTE>
<P>affects the client interface.  This feature is useful in case it is
necessary to link the client and server interfaces together.  Without
this feature, name conflicts would occur.
<P>The <EM>header_line</EM> defines the name of this subsystem.  The subsystem
name is used in generating a unique for the <EM>execute request</EM> routine.
<P>The <EM>default_timeout</EM> is used in both the server and client stubs. 
Both are specified in seconds.  Zero is interpreted as an infinite timeout
value.  The value specifies the timeout value used on RPC2_MakeRPC ()
and RPC2_SendResponse () calls in the client and server stubs respectively. 
The timeout parameter may be overriden for individual procedures by
specifying a <EM>timeout_override</EM>.  Note that the timeouts apply to
each individual Unix blocking system call, not to the entire RPC2 procedure.
<P>The <EM>new_connection</EM> is used to designate at most one server procedure
that will be called when the subsystem receives the initial RPC2 connection. 
The new connection procedure must have 4 arguments in the following
order with the following usages and types:
<BLOCKQUOTE><CODE>
<PRE>

(IN RPC2_Integer: SideEffectType,
 IN RPC2_Integer: SecurityLevel,
 IN RPC2_Integer: EncryptionType,
 IN RPC2_CountedBS: ClientIdent,
</PRE>
</CODE></BLOCKQUOTE>
<P>
<P>where <CODE> SideEffectType, SecurityLevel, EncryptionType,</CODE> and <CODE> ClientIdent</CODE> have the values
that were specified on the clients call to RPC2_Bind.  Note that RP2Gen will automatically
perform an RPC2_Enable  call at the end of this routine.
If no new connection procedure is specified, then the call to the <EM>execute
request</EM> routine with the initial connection request will return RPC2_FAIL.
<P>The <EM>usage</EM> tells whether the data for the parameter is to be copied
in, copied out, or copied in both directions.  The <EM>usage</EM> and <EM>type_name</EM>
specifications together tell how the programmer should declare the parameters
in the server code.
<P>
<P>
<P>
<H3>Example 1: Common Definitions for Coda File System</H3>

<P>
<BLOCKQUOTE><CODE>
<PRE>
/*
 * Include file common to callback.rpc2, vice.rpc2 and res.rpc2
 */

typedef RPC2_Unsigned   VolumeId;
typedef VolumeId               VolId;
typedef RPC2_;Unsigned  VnodeId;
typedef RPC2_;Unsigned  Unique;

typedef RPC2_Struct 
        {
        VolumeId        Volume;
        VnodeId         Vnode;
        Unique          Unique;
        } ViceFid;

typedef RPC2_Struct
        {
        RPC2_Unsigned   Host;
        RPC2_Unsigned   Uniquifier;
        } ViceStoreId;

typedef RPC2_Struct
        {
        RPC2_Integer    Site0;
        RPC2_Integer    Site1;
        RPC2_Integer    Site2;
        RPC2_Integer    Site3;
        RPC2_Integer    Site4;
        RPC2_Integer    Site5;
        RPC2_Integer    Site6;
        RPC2_Integer    Site7;
        } ViceVersionArray;

typedef RPC2_Struct
        {
        ViceVersionArray        Versions;
        ViceStoreId     StoreId;
        RPC2_Unsigned   Flags;
        } ViceVersionVector;

typedef RPC2_Unsigned   UserId;
typedef RPC2_Unsigned   FileVersion;
typedef RPC2_Unsigned   Date;
typedef RPC2_Integer    Rights;

typedef RPC2_Enum 
        { 
        Invalid = 0,
        File = 1, 
        Directory = 2, 
        SymbolicLink = 3 
        } ViceDataType;

typedef RPC2_Enum
        {
        NoCallBack = 0,
        CallBackSet = 1,
        BidFidReleased = 3
        } CallBackStatus;


typedef RPC2_Struct
        {
        RPC2_Unsigned   InterfaceVersion;
        ViceDataType    VnodeType;
        RPC2_Integer    LinkCount;
        RPC2_Unsigned   Length;
        FileVersion     DataVersion;
        ViceVersionVector       VV;
        Date            Date;
        UserId          Author;
        UserId          Owner;
        CallBackStatus  CallBack;
        Rights          MyAccess;
        Rights          AnyAccess;
        RPC2_Unsigned   Mode;
        VnodeId         vparent;
        Unique          uparent;
        } ViceStatus;
</PRE>
</CODE></BLOCKQUOTE>
<P>
<P>
<P>
<H3>Example 2: The Coda Resolution Subsystem Interface</H3>

<P>
<BLOCKQUOTE><CODE>
<PRE>
/* res.rpc2 
 * Defines the resolution subsystem interface
 * 
 * Created Puneet Kumar, June 1990
 */
server prefix "RS";
client prefix "Res";

Subsystem "resolution";

#define RESPORTAL       1361
#define RESOLUTIONSUBSYSID 5893

/* 
Return codes from the servers on resolution subsystem
*/
#define RES_FAILURE     -512
#define RES_SUCCESS     0
#define RES_TIMEDOUT    -513
#define RES_NOTRUNT     -514
#define RES_BADOPLIST   -515

#include "vcrcommon.rpc2"

typedef RPC2_Struct
        {
        RPC2_Integer    status;
        RPC2_Unsigned   Author;
        RPC2_Unsigned   Owner;
        RPC2_Unsigned   Date;
        RPC2_Unsigned   Mode;
        } ResStatus;

typedef RPC2_Struct
        {
        RPC2_Integer            LogSize;
        ViceVersionVector       VV;
        } ResVolParm;

typedef RPC2_Enum
        {
        FetchStatus = 0,
        FetchSData = 1
        } ResFetchType;

typedef RPC2_Enum
        {
        ResStoreStatus = 0,
        ResStoreData = 1
        } ResStoreType;

COP2     (IN ViceStoreId StoreId,
                 IN ViceVersionVector UpdateSet);

NewConnection (IN RPC2_Integer SideEffectType,
                 IN RPC2_Integer SecurityLevel,
                 IN RPC2_Integer EncryptionType,
                 IN RPC2_CountedBS ClientIdent)
                 NEW_CONNECTION;

ForceFile    (IN ViceFid Fid,
                 IN ResStoreType Request,
                 IN RPC2_Integer Length,
                 IN ViceVersionVector VV,
                 IN ResStatus Status,
                 IN OUT SE_Descriptor BD);

LockAndFetch (IN ViceFid Fid, 
                 IN ResFetchType Request, 
                 OUT ViceVersionVector VV,
                 OUT RPC2_Integer logsize);

UnlockVol    (IN VolumeId Vid);

MarkInc      (IN ViceFid Fid);

FetchFile (IN ViceFid Fid, 
                 IN RPC2_Unsigned PrimaryHost,
                 OUT ResStatus Status,
                 IN OUT SE_Descriptor BD);

ForceDirVV (IN ViceFid Fid,
                 IN ViceVersionVector VV);

DoForceDirOps (IN ViceFid Fid,
                 IN ViceStatus status,
                 IN OUT RPC2_CountedBS AccessList,
                 OUT RPC2_Integer rstatus,
                 IN OUT SE_Descriptor sed);

GetForceDirOps  (IN ViceFid Fid,
                 OUT ViceStatus status, 
                 IN OUT RPC2_CountedBS AccessList,
                 IN OUT SE_Descriptor sed);

FetchLog (IN ViceFid Fid,
                 OUT RPC2_Integer logsize,
                 IN OUT SE_Descriptor sed);

DirResPhase2 (IN ViceFid Fid,
                 IN ViceStoreId logid,
                 OUT ViceStatus status,
                 IN RPC2_BoundedBS pbinc);

DirResPhase1 (IN ViceFid Fid, 
                 IN RPC2_Integer size,
                 IN OUT ViceStatus status,
                 IN OUT RPC2_BoundedBS piggyinc,
                 IN OUT SE_Descriptor sed);

DirResPhase3 (IN ViceFid Fid,
                 IN ViceVersionVector UpdateSet,
                 IN OUT SE_Descriptor sed);
</PRE>
</CODE></BLOCKQUOTE>
<P>
<P>
<H2><A NAME="ss3.4">3.4 Command Line Parameters</A>
</H2>

<P>In addition, several command line flags are available to modify the behavior of rp2gen :
<DL>
<DT><B>-c <CODE>file</CODE></B><DD><P>Specify the name of the client .c file.
<DT><B>-s <CODE>file</CODE></B><DD><P>Specify the name of the server .c file. 
<DT><B>-h <CODE>file</CODE></B><DD><P>Specify the name of the header file.
<DT><B>-m <CODE>file</CODE></B><DD><P>Specify the name of the MultiRPC stub file.
<DT><B>-I <CODE>path</CODE></B><DD><P>Additional path to look for included files.
<DT><B>-e,-neterrors</B><DD><P>Translate system-specfic error codes to caller's system-specfic codes.
<DT><B>-cplusplus</B><DD><P>Generate C++ compatible code in .cc files.
</DL>
<P>
<H2><A NAME="ss3.5">3.5 The C Interface</A>
</H2>

<P>This section describes the <B>C interface</B> generated by RP2GEN.  The following
table shows the relationship between RP2GEN parameter declarations and
the corrseponding C parameter declarations.
<P>
<CENTER><TABLE BORDER><TR><TD>
<BR>
RPC2 Type </TD><TD> <B>in</B> </TD><TD> <B>out</B> </TD><TD> <B>in out</B>&gt;</TD></TR><TR><TD>
RPC2_Integer </TD><TD> long </TD><TD> long * </TD><TD> long *</TD></TR><TR><TD>
RPC2_Unsigned </TD><TD> unsigned long </TD><TD> unsigned long * </TD><TD> unsigned long *</TD></TR><TR><TD>
RPC2_Byte </TD><TD> unsigned char </TD><TD> unsigned char * </TD><TD> unsigned char *</TD></TR><TR><TD>
RPC2_String </TD><TD> unsigned char * </TD><TD> unsigned char * </TD><TD> unsigned char *</TD></TR><TR><TD>
RPC2_CountedBS </TD><TD> RPC2_CountedBS * </TD><TD> RPC2_CountedBS * </TD><TD> RPC2_CountedBS *</TD></TR><TR><TD>
RPC2_BoundedBS </TD><TD> RPC2_BoundedBS * </TD><TD> RPC2_BoundedBS * </TD><TD> RPC2_BoundedBS *</TD></TR><TR><TD>
RPC2_EncryptionKey </TD><TD> RPC2_EncryptionKey </TD><TD> RPC2_EncryptionKey * </TD><TD> RPC2_EncryptionKey *</TD></TR><TR><TD>
</TD></TR><TR><TD>
SE(Descriptor) </TD><TD> <EM>illegal</EM> </TD><TD> <EM>illegal</EM> </TD><TD> </TD></TR><TR><TD>
SE(Descriptor) *</TD></TR><TR><TD>
RPC2_Enum <EM>name</EM> </TD><TD> <EM>name</EM> </TD><TD> <EM>name</EM> * </TD><TD> <EM>name</EM> *</TD></TR><TR><TD>
RPC2_Struct <EM>name</EM> </TD><TD> <EM>name</EM> * </TD><TD> <EM>name</EM> * </TD><TD> <EM>name</EM> *</TD></TR><TR><TD>
RPC2_Byte <EM>name[...</EM> </TD><TD> <EM>name</EM> </TD><TD> <EM>name</EM> </TD><TD> <EM>name</EM></TD></TR><TR><TD>

<CAPTION>
<A NAME="CDecls"></A> 
RP2Gen representation of parameters</CAPTION>
</TD></TR></TABLE></CENTER>
<P>
<P>In all cases it is the caller's responsibility to allocate storage for
all parameters.  This means that for <CODE> IN </CODE>and<CODE> IN OUT </CODE>parameters of a non-fixed
type, it is the callee's responsibility to ensure that the value to
be copied back to the caller does not exceed the storage allocated by
the callee.
<P>The caller must call an RPC2 procedure with an initial implicit argument
of type RPC2_Handle  that indicates the destination address(es) of the
target process(es).  The callee must declare the C routine that corresponds
to an RPC2 procedure with an initial implicit argument of type
RPC2_Handle. 
Upon invocation, this argument will be bound to the address of a handle
that indicates the address of the caller.
<P>RP2GEN also generates a routine that serves to decode an RPC2 request.
The name of this routine is "<EM>subsystem_name_ExecuteRequest</EM>",
and it is invoked as follows:
<P>
<BLOCKQUOTE><CODE>
int <EM>subsystem_name_ExecuteRequest</EM>(cid, Request, bd)
RPC2_Handle cid;
RPC2_PacketBuffer *Request;
SE_Descriptor *bd;
</CODE></BLOCKQUOTE>
<P>
<P>
<P>This routine will unmarshall the arguments and call the appropriate
interface routine.  The return value from this routine will be the return
value from the interface routine.
<P>The client program is responsible for actually making the connection
with the server and must pass the connection id as an additional parameter (the first) on each call to the interface.
<P>
<P>
<P>
<H2><A NAME="ss3.6">3.6 External Data Representations</A>
</H2>

<P>This section defines the external data representation used by RP2GEN,
that is, the representation that is sent out over the wire.  Each item
sent over on the wire is required to be a multiple of 4 (8-bit) bytes.  (Items
are padded as necessary to achieve this constraint.)  The bytes of an
item are numbered 0 through <EM>n</EM>-1 (where <EM>n</EM> <EM>mod</EM> 4 = 0).  The
bytes are read and written such that byte <EM>m</EM> always precedes byte
<EM>m</EM>+1.
<P>
<P>
<DL>
<DT><B>RPC2_Integer</B><DD><P>An RPC2_Integer  is a 32-bit item that encodes an integer represented
in twos complement notation.  The most significant byte of the integer
is 0, and the least significant byte is 3.
<P>
<DT><B>RPC2_Unsigned</B><DD><P>An RPC2_Unsigned  is a 32-bit item that encodes an unsigned integer. 
The most significant byte of the integer is 0, the least significant
byte is 3.
<P>
<DT><B>RPC2_Byte</B><DD><P>An RPC2_Byte  is transmitted as a single byte followed by three padding
bytes.
<P>
<DT><B>RPC2_String</B><DD><P>An RPC2_String  is a C-style null-terminated character string.  It is
sent as an RPC2_Integer  indicating the number of characters to follow,
not counting the null byte, which is, however, sent.  This is followed
by bytes representing the characters (padded to a multiple of 4), where
the first character (i.e., farthest from the null byte) is byte 0. 
An RPC2_String  of length 0 is representing by sending an RPC2_Integer 
with value 0, followed by a 0 byte and three padding bytes.
<P>
<DT><B>RPC2_CountedBS</B><DD><P>An RPC2_CountedBS  is used to represent a byte string of arbitrary
length.  The byte string is not terminated by a null byte.  An RPC2_CountedBS 
is sent as an RPC2_Integer  representing the number of bytes, followed
by the bytes themselves (padded to a multiple of 4 .  The byte with
the lowest address is sent as byte 0.
<P>
<DT><B>RPC2_BoundedBS</B><DD><P>An RPC2_BoundedBS  is intended to allow you to remotely play the game
that C programmers play: allocate a large buffer, fill in some bytes,
then call a procedure that takes this buffer as a parameter and replaces
its contents by a possibly longer sequence of bytes.  An RPC2_BoundedBS 
is transmitted as two RPC2_Integer s representing the maximum and current
lengths of the byte strings.  This is followed by the  bytes representing
the contents of the buffer (padded to a multiple of 4).  The byte with
the lowest address is byte 0.
<P>
<DT><B>RPC2_EncryptionKey</B><DD><P>An RPC2_EncryptionKey  is used to transmit an encryption key (surprise!). 
A key is sent as a sequence of RPC2_KEYSIZE  bytes, padded to a multiple
of 4.  Element 0 of the array is byte 0.
<P>
<DT><B>SE(Descriptor)</B><DD><P>Objects of type @SE(Descriptor) are never transmitted.
<P>
<DT><B>RPC2_Struct</B><DD><P>An RPC2_Struct  is transmitted as a sequence of items representing its
fields.  The fields are sent in textual order of declaration (i.e.,
from left to right and top to bottom).  Each field is sent using, recursively,
its RPC2 representation.
<P>
<DT><B>RPC2_Enum</B><DD><P>An RPC2_Enum  has the same representation has an RPC2_Integer , and the
underlying integer used by the compiler is transmitted as the value
of an RPC2_Enum.  (Note that in C, this underlying value may be specified
by the user.  This is recommended practice.)
<P>
<DT><B>Array</B><DD><P>The total number of bytes transmitted for an array must be
a multiple of 4.
However, the number of bytes sent for each element depends on the type of
the element.
</DL>
<P>
<P>Currently, only arrays of RPC2_Byte  are defined.
The elements of such an array are each sent as a single byte (no padding),
with array element, <EM>n-1,</EM> preceding element, <EM>n</EM>.
<P>
<P>
<P>
<P>
<P>
<HR>
<A HREF="rpc2_manual-4.html">Next</A>
<A HREF="rpc2_manual-2.html">Previous</A>
<A HREF="rpc2_manual.html#toc3">Contents</A>
</BODY>
</HTML>