Prototyped Calls
- Whether the call is bound (procedure) or dynamic (program)
- How to find the program or procedure (the external name)
- The number and nature of the parameters
- Which parameters must be passed, and which are optionally passed
- Whether operational descriptors are passed (for a procedure)
- The data type of the return value, if any (for a procedure)
The prototype is used by the compiler to call the program or procedure correctly, and to ensure that the caller passes the correct parameters. Figure 1 shows a prototype for a procedure FmtCust, which formats various fields of a record into readable form. It has two output parameters.
// Prototype for procedure FmtCust (Note the PR on definition
// specification.) It has two output parameters.
D FmtCust PR
D Name 100A
D Address 100A
To format an address, the application calls a procedure FmtAddr. FmtAddr has several input parameters, and returns a varying character field. Figure 2 shows the prototype for FmtAddr.
//---------------------------------------------------------
// FmtAddr - procedure to produce an address in the form
//---------------------------------------------------------
D FmtAddr PR 100A VARYING
D streetNum 10I 0 CONST
D streetName 50A CONST
D city 20A CONST
D state 15A CONST
D zip 5P 0 CONST
If the procedure is coded in the same module as the call, specifying the prototype is optional. If the prototype is not specified, the compiler will generate the prototype from the procedure interface. However, if the procedure is exported and it is also called from another RPG module or program, a prototype should be specified in a copy file, and the copy file should be copied into both the calling module and the module that is exporting the procedure.
If the program or procedure is prototyped, you call it with CALLP or within an expression if you want to use the return value. You pass parameters in a list that follows the name of the prototype, for example, name (parm1 : parm2 : …).
Figure 3 shows a call to FmtCust. Note that the names of the output parameters, shown above in Figure 1, do not match those in the call statement. The parameter names in a prototype are for documentation purposes only. The prototype serves to describe the attributes of the call interface. The actual definition of call parameters takes place inside the procedure itself.
C CALLP FmtCust(RPTNAME : RPTADDR)
- Programs that are on the system at run time
- Exported procedures in other modules or service programs that are bound in the same program or service program
- Subprocedures in the same module
FmtCust calls FmtAddr to format the address. Because FmtCust wants to use the return value, the call to FmtAddr is made in an expression. Figure 4 shows the call.
//--------------------------------------------------------------
// Call the FmtAddr procedure to handle the address
//--------------------------------------------------------------
Address = FmtAddress (STREETNUM : STREETNAME :
CITY : STATE : ZIP);
- Prototyped parameters can be passed in several ways: by reference, by value (for procedures only), or by read-only reference. The default method for RPG is to pass by reference. However, passing by value or by read-only reference gives you more options for passing parameters.
- If the prototype indicates that it is allowed for a given parameter, you
may be able to do one or more of the following:
- Pass *OMIT
- Leave out a parameter entirely
- Pass a shorter parameter than is specified (for character and graphic parameters, and for array parameters)