With so many modules making up an application, inter-module communication becomes an important issue. The most common AS/400 techniques for passing information between modules include:
Parameter passing.
Reading and writing to an external data area.
Exporting and importing variables.
Stacks and data queues.
Message sending.
Data queues are considered to be the fastest way to send large volumes of information between applications. This chapter, however, discusses parameter passing, data area handling, and exporting and importing variables.
Parameter passing is perhaps the most effective method for communicating between program modules. Most operating systems, such as the AS/400 Operating System/400 (OS/400), support parameters in a consistent manner throughout all high-level languages. This makes it easy to send data from RPG programs to other programs and procedures regardless of the language in which they are written.
When a program transfers control to another program, it is referred to as calling a procedure or calling a program. The program doing the calling is referred to as the calling program or by the simpler term caller. The program that receives control is referred to as the called program or by the simpler term callee.
For example, if a program named PGMA (pronounced "program A") calls a program named PGMB (pronounced "program B"), PGMA is the calling program, and PGMB is the called program. See Figure 9.3.
Figure 9.3: Program-to-program call.
Parameters are passed between program modules and procedures. RPG cannot pass parameters to subroutines. For program-to-program calls, the PLIST (parameter list) operation normally defines the parameter interface for the call. Factor 1 of the PLIST operation, in the calculation specifications, identifies the name of the parameter list that is being defined. Figure 9.4 shows the syntax for a named parameter list.
![]() |
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq... C MATH PLIST C PARM Result 7 2 C PARM Value1 5 2 C PARM Value2 5 2 C PARM Operation 1
![]() |
In Figure 9.4, the parameter list named MATH is defined. The individual fields that are passed between modules are called parameters and are defined by the PARM (Parameter Declaration) operation. In this example, four fields (RESULT, VALUE1, VALUE2, and OPERATION) are declared as parameters on the parameter list MATH. The number of parameters passed between programs is implied by the number of PARM operations.
A special-purpose parameter list, known as the entry parameter list, is used to receive parameters into a called program and return them to the calling program. An entry parameter list (often referred to as the entry PLIST) is identified with *ENTRY in factor 1 of the PLIST operation. For example, if the parameter list MATH is used to call a program named PGMB, the entry parameter list for PGMB is written as shown in Figure 9.5.
![]() |
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq... C *ENTRY PLIST C PARM p1_Result 7 2 C PARM p2_Value1 5 2 C PARM p3_Value2 5 2 C PARM p4_Oper 1
![]() |
Figure 9.5 shows a typical entry PLIST. The name implies that the entry PLIST is the entry point into the program; it is not. While the entry PLIST can appear anywhere in the program, RPG always starts processing at the beginning of the RPG cycle.
Each parameter of the parameter list MATH, shown in Figure 9.4, has a corresponding parameter in the called program shown in Figure 9.5. Typically, identical parameter lists are defined in the calling and called programs. Field names used on the entry parameter list normally match those of the calling program's parameter list. In the example shown in Figure 9.5, however, this is not illustrated.
On the System/38 and AS/400, parameters are traditionally passed by reference, not value. The parameter's address in memory (a pointer) is transferred between programs. The data itself is accessed through a field, array, or data structure. Internally, RPG accesses the data through the address; however, this is entirely transparent to the application program.
Parameters also can be passed by value. This causes the system to make a copy of the parameter's data and store that data in a temporary location. A pointer to that temporary location is then passed to the called procedure. Parameters that are passed by value are referred to as read-only parameters. Parameters passed by value can be transferred only between procedures, not programs.
When a program is called, the fields specified on the entry PLIST are assigned the address of the parameters being passed to the program. This means that fields on the entry PLIST in the called program actually point to the original data in the calling program. Any changes to the data, made by the called program, automatically affect the field values in the calling program.
For example, assume a field named RESULT in PGMA has a memory address of X'00287DC0' and is a parameter used on a call operation to the PGMB program. In PGMB, the ANSWER field is specified in the same relative position on the *ENTRY parameter list as the RESULT field.
When PGMA calls PGMB, the address of the field RESULT from PGMA is assigned to the ANSWER field in PGMB. As shown in Figure 9.6, the ANSWER field is assigned an address of X'00287DC0'. This is referred to as parameter passing by reference.
Figure 9.6: Parameter passing by reference.
The called program should define a parameter list that can accommodate (i.e., receive) all of the incoming parameters. The names and attributes (e.g., length, type) of the fields being used as parameters in the calling program do not have to match those defined in the called program. However, if the attribute of the parameters in the calling and called programs do not match, data integrity can be compromised. For example, a character field containing blanks could be passed to a numeric field, which would cause an error.
This style of call interface (parameter lists) is referred to as the weak parameter module. There is no compile-time parameter checking, validation, or integrity. For this reason, the prototyped call interface exists as an alternative call interface. For more information, see the subheading Prototyped Call.
Assume the parameters of the MATH parameter list are assigned the values shown in Figure 9.7.
![]() |
RESULT = 0.0 /* This value is returned from the called program. */ VALUE1 = 3.5 VALUE2 = 6.0 OPERATION = *
![]() |
Both the calling program and the called program reference these values. If the value of one of the fields is changed by the called program, the field in the calling program is also changed because both fields reference the same memory location.
When a program is called and the MATH parameter list is passed to it, a series of four parameter addresses is transferred to the called program. Those addresses represent the location in memory of the values assigned to the parameter fields.
Table 9.1 lists an example memory address for each field used on the MATH parameter list (see also Figure 9.4) and the data represented by those fields.
Field Name on PLIST | Memory Address | Data |
---|---|---|
RESULT | X'00003618' | X'0000000F' |
VALUE1 | X'000046C5' | X'00350F' |
VALUE2 | X'000046C8' | X'00600F' |
OPER | X'000052D6' | * |
As mentioned earlier, the name of the fields used for the called program's parameter list don't have to match those used in the calling program's parameter list. The sequence of the parameters is important, however. Corresponding parameters in different programs must be in the same relative location on the parameter list.
For example, if a program named PGMA uses the MATH parameter list (see Figure 9.4) to call the program named PGMB, the fields used on the entry parameter list in PGMB are assigned the same address as the corresponding parameter in PGMA. Therefore, the fields of the entry parameter list in PGMB have access to the same physical data as the corresponding fields in PGMA. See Table 9.2.
Field Name on Plist | Memory Address | Data |
---|---|---|
ANSWER | X'003618' | X'0002100F' |
FACT1 | X'0046C5' | X'00350F' |
FACT2 | X'0046C8' | X'00600F' |
OPER | X'0052D6' | * |
In Table 9.2, note that the value for the ANSWER field is specified. This assumes that PGMB has finished processing and is about to return to its caller. The memory location of each parameter is not affected, but the data itself can be modified.
Figure 9.8 contains the program listing for the example PGMA. It contains the parameter list definition for the MATH parameter list. Because parameter lists are declarations, they can be specified anywhere in the program. The technique shown in Figure 9.8 uses a named parameter list. The MATH parameter list is defined independently from the CALL operation and, therefore, can be used by more than one CALL operation.
Figure 9.8: PGMA calls PGMB with a named parameter list.
Figure 9.9 illustrates a called program. The entry parameter list (lines 1 to 5) contains four parameters. While this program uses all of the parameters passed to it, only the first parameter—the ANSWER field—is modified by the program.
![]() |
.....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq 0001 C *ENTRY PLIST 0002 C PARM Answer 7 2 0003 C PARM Fact1 5 2 0004 C PARM Fact2 5 2 0005 C PARM OpCode 1 0006 C SELECT 0007 C When OpCode = '+' 0008 C Eval Answer = Fact1 + Fact2 0009 C When OpCode = '-' 0010 C Eval Answer = Fact1 - Fact2 0011 C When OpCode = '*' 0012 C Eval Answer = Fact1 * Fact2 0013 C When OpCode = '/' 0014 C Eval Answer = Fact1 / Fact2 0015 C EndSL 0016 C MOVE *ON *INLR
![]() |
A parameter list can be specified immediately following a CALL operation. In this situation, the parameter list is assigned exclusively to the CALL operation that precedes it. See Figure 9.10.
![]() |
.....CSRn01..............OpCode(ex)Extended-factor2++++++++++++++++++++++++++++ 0001 C EVAL Result = 0 0002 C EVAL Value1 = 3.5 0003 C EVAL Value2 = 6 0004 C EVAL Operation = '*' .....CSRn01Factor1+++++++OpCode(ex)Factor2+++++++Result++++++++Len++DcHiLoEq.... 0005 C CALL 'PGMB' 0006 C PARM RESULT 7 2 0007 C PARM VALUE1 5 2 0008 C PARM VALUE2 5 2 0009 C PARM OPERATION 1 0010 C MOVE *ON *INLR
![]() |
Factor 2 can be specified for a PARM operation. When a program calls another program, the content of factor 2 of the PARM operation (if present) is copied into the result field. This allows the program to avoid explicitly moving the parameter data into the parameter fields. See Figure 9.11.
Figure 9.11: Parameter movement upon calling a program.
Factor 1 can be specified for a PARM operation. When a program is called, the contents of the result fields of the entry parameter list are copied into factor 1. See Figure 9.12.
Figure 9.12: Parameter movement upon entering a called program.
A program ends when it returns to its caller. The content of factor 2 of its entry parameter list is copied into the result field. See Figure 9.13.
Figure 9.13: Parameter movement upon exiting a called program.
Upon leaving a program, factor 2 is copied to the result field. This effect, shown in Figure 9.13, is similar to the one shown in Figure 9.11.
When a called program returns control to its caller, the result fields of the parameter list in the calling program are copied into factor 1. See Figure 9.14.
Figure 9.14: Parameter movement upon returning to the calling program.
Table 9.3 lists a cross reference of the figures that illustrate program-to-program call operations with parameters being passed between the programs.
Call/Return Action | Figure Illustrating Action in PGMA | Figure Illustrating Action in PGMB |
---|---|---|
PGMA calls PGMB | Figure 9.11 | Figure 9.12 |
PGMB ends; control returns to PGMA | Figure 9.14 | Figure 9.13 |
Parameters can be virtually any RPG field, data structure, or array name. A technique often used to pass multiple fields involves using a data structure. The fields are defined as data-structure subfields. This avoids having to code a PARM operation for each parameter that is passed. Data-structure subfields cannot be passed as parameters themselves; passing a data structure avoids this restriction. For example, if the fields RESULT, VALUE1, VALUE2, and OPERATION need to be passed, a single parameter can be defined that passes a data structure. The data structure would be made up of the four subfields. See Figure 9.15.
Figure 9.15: Data structure used as a parameter.
The data structure PARMDATA (line 1) is made up of four data structure subfields: RESULT, VALUE1, VALUE2, and OPERATION (lines 2 to 5, respectively). When PGMB is called (line 6) and is passed its single parameter, all the data stored in each of the four subfields becomes available to the called program PGMB. To address the four subfields of the data structure, a parameter should be declared by the called program as a data structure. See Figure 9.16.
Figure 9.16: Program receiving a data structure as a parameter.
When the program listed in Figure 9.16 receives control, the PARMDATA parameter is assigned the address of the corresponding parameter in the caller program. The PARMDATA data structure is then used to access the data at that address in memory. Note that, because this is an *ENTRY PLIST parameter, the PARMDATA data structure cannot be initialized with the INZ keyword.