Professional Documents
Culture Documents
com/infocenter/ratde
vz/v7r5/index.jsp?
topic=/com.ibm.ent.cbl.zos.doc/topics/PGan
dLR/tasks/tpchk04.htm
Examples: static and dynamic CALL statements
This example shows how you can code static and dynamic calls.
The following example shows how you would code static calls:
The following example shows how you would code dynamic calls:
DATA DIVISION.
WORKING-STORAGE SECTION.
77 PGM-NAME PICTURE X(8).
01 RECORD-2 PIC x. (6)
01 RECORD-1. (2)
05 PAY PICTURE S9(5)V99.
05 HOURLY-RATE PICTURE S9V99.
05 HOURS PICTURE S99V9.
. . .
PROCEDURE DIVISION.
. . .
MOVE "SUBPROG" TO PGM-NAME.
CALL PGM-NAME USING RECORD-1. (1)
CANCEL PGM-NAME.
MOVE "PAYMASTR" TO PGM-NAME. (4)
CALL PGM-NAME USING RECORD-1 RECORD-2. (5)
STOP RUN.
The following example shows a called subprogram that is called by each of the two
preceding calling programs:
IDENTIFICATION DIVISION.
PROGRAM-ID. SUBPROG.
DATA DIVISION.
LINKAGE SECTION.
01 PAYREC. (2)
10 PAY PICTURE S9(5)V99.
10 HOURLY-RATE PICTURE S9V99.
10 HOURS PICTURE S99V9.
77 PAY-CODE PICTURE 9. (6)
PROCEDURE DIVISION USING PAYREC. (1)
. . .
EXIT PROGRAM. (3)
ENTRY "PAYMASTR" USING PAYREC PAY-CODE. (5)
. . .
GOBACK. (7)
(1)
Processing begins in the calling program. When the first CALL statement is
executed, control is transferred to the first statement of the PROCEDURE
DIVISION in SUBPROG, which is the called program.
In each of the CALL statements, the operand of the first USING option is
identified as RECORD-1.
(2)
When SUBPROG receives control, the values within RECORD-1 are made
available to SUBPROG; however, in SUBPROG they are referred to as PAYREC.
The PICTURE character-strings within PAYREC and PAY-CODE contain the same
number of characters as RECORD-1 and RECORD-2, although the descriptions
are not identical.
(3)
When processing within SUBPROG reaches the EXIT PROGRAM statement,
control is returned to the calling program. Processing continues in that
program until the second CALL statement is issued.
(4)
In the example of a dynamically called program, because the second CALL
statement refers to another entry point within SUBPROG, a CANCEL statement
is issued before the second CALL statement.
(5)
With the second CALL statement in the calling program, control is again
transferred to SUBPROG, but this time processing begins at the statement
following the ENTRY statement in SUBPROG.
(6)
The values within RECORD-1 are again made available to PAYREC. In addition,
the value in RECORD-2 is now made available to SUBPROG through the
corresponding USING operand, PAY-CODE.
When control is transferred the second time from the statically linked
program, SUBPROG is made available in its last-used state (that is, if any
values in SUBPROG storage were changed during the first execution, those
changed values are still in effect). When control is transferred from the
dynamically linked program, however, SUBPROG is made available in its initial
state, because of the CANCEL statement that has been executed.
(7)
When processing reaches the GOBACK statement, control is returned to the
calling program at the statement immediately after the second CALL
statement.
In any given execution of the called program and either of the two calling programs,
if the values within RECORD-1 are changed between the time of the first CALL and the
second, the values passed at the time of the second CALL statement will be the
changed, not the original, values. If you want to use the original values, you must
save them.
In this case, with the CALL literal statement, the called subprogram will be link-
edited with the main program into one load module. The CALL identifier statement
results in the dynamic invocation of a separate load module.
When a dynamic CALL statement and a static CALL statement to the same
subprogram are issued within one program, a second copy of the subprogram is
loaded into storage. Because this arrangement does not guarantee that the
subprogram will be left in its last-used state, results can be unpredictable.
DYNAM
Use DYNAM to cause nonnested, separately compiled programs invoked through the
CALL literal statement to be loaded (for CALL) and deleted (for CANCEL) dynamically
at run time. (CALL identifier statements always result in a runtime load of the target
program and are not affected by this option.)
.-NODYNAM-.
>>-+---------+-------------------------------------------------><
'-DYNAM---'
Restriction: The DYNAM compiler option must not be used in the following cases:
• COBOL programs that are processed by the CICS translator or the CICS
compiler option
• COBOL programs that have EXEC SQL statements and are run under CICS or
DB2 call attach facility (CAF)
If your COBOL program calls programs that have been linked as dynamic link
libraries (DLLs), you must not use the DYNAM option. You must instead compile the
program with the NODYNAM and DLL options.
The load module that you want to dynamically call must be in an MVS load library
rather than in the hierarchical file system.
If subprograms are called in only a few conditions, you can use dynamic calls to
bring in the subprograms only when needed.
If the subprograms are very large or there are many of them, using static calls might
require too much main storage. Less total storage might be required to call and
cancel one, then call and cancel another, than to statically call both.
If you are concerned about ease of maintenance, dynamic calls can help.
Applications do not have to be link-edited again when dynamically called
subprograms are changed.
When you cannot use the INITIAL attribute to ensure that a subprogram is placed in
its unused state each time that it is called, you can set the unused state by using a
combination of dynamic CALL and CANCEL statements. When you cancel a
subprogram that was first called by a COBOL program, the next call causes the
subprogram to be reinitialized to its unused state.
Using the CANCEL statement to explicitly cancel a subprogram that was dynamically
loaded and branched to by a non-COBOL program does not result in any action being
taken to release the subprogram's storage or to delete the subprogram.
Suppose you have an OS/VS COBOL or other AMODE 24 program in the same run unit
with Enterprise COBOL programs that you want to run in 31-bit addressing mode.
COBOL dynamic call processing includes AMODE switching for AMODE 24 programs that
call AMODE 31 programs, and vice versa. To have this implicit AMODE switching done,
you must use the Language Environment runtime option ALL31(OFF). AMODE
switching is not performed when ALL31(ON) is set.
When AMODE switching is performed, control is passed from the caller to a Language
Environment library routine. After the switching is performed, control passes to the
called program; the save area for the library routine will be positioned between the
save area for the caller program and the save area for the called program.
If you do not know the program-name to be called until run time, use the format
CALL identifier, where identifier is a data item that will contain the name of the called
program at run time. For example, you could use CALL identifier when the program
to be called varies depending on conditional processing in your program. CALL
identifier is always dynamic, even if you use the NODYNAM compiler option.
You cannot delete a statically called program, but you can delete a
dynamically called program. Using a dynamic call and then a CANCEL
statement to delete the dynamically called program after it is no longer
needed in the application (and not after each call to it) might require less
storage than using a static call.
Related concepts
CALL identifier, where identifier is a data item that contains the name of a nonnested
subprogram at run time, always results in the target subprogram being loaded when
it is called. CALL literal, where literal is the explicit name of a nonnested target
subprogram, can be resolved either statically or dynamically.
With CALL identifier, the name of the DLL must match the name of the target entry
point.
With CALL literal, if the NODYNAM compiler option is in effect, either static or dynamic
linking can be done. If DYNAM is in effect, CALL literal is resolved in the same way as
CALL identifier: the target subprogram is loaded when it is called, and the name of
the DLL must match the name of the target entry point.
These call definitions apply only in the case of a COBOL program calling a nonnested
program. When a COBOL program calls a nested program, the call is resolved by the
compiler without any system intervention.
Static linking occurs when a calling program is linked to a called program in a single
executable module. When the program is loaded, the operating system places into
memory a single file that contains the executable code and data.
The result of statically linking programs is an .EXE file or dynamic link library (DLL)
subprogram that contains the executable code for multiple programs. This file
includes both the calling program and the called program.
The primary advantage of static linking is that you can create self-contained,
independent programs. In other words, the executable program consists of one part
(the .EXE file) that you need to keep track of. Static linking has these disadvantages:
• Linked external programs are built into the executable files, making these
files larger.
• You cannot change the behavior of executable files without relinking them.
• External called programs cannot be shared, requiring that duplicate copies of
programs be loaded in memory if more than one calling program needs to
access them.
Dynamic linking lets several programs use a single copy of an executable module.
The executable module is separate from the programs that use it. You can build
several subprograms into a DLL. Calling programs can use these subprograms as if
they were part of the executable code of the calling program. You can change the
dynamically linked subprograms without recompiling or relinking the calling program.
DLLs are typically used to provide common functions for a number of programs. For
example, you can use DLLs to implement subprogram packages, subsystems, and
interfaces to other programs, or to create object-oriented class libraries.
You can dynamically link files with the supplied runtime DLLs and with your own
COBOL DLLs.
In addition to making calls between Enterprise COBOL programs, you can also make
static and dynamic calls between Enterprise COBOL and programs compiled with
older compilers in all environments including CICS.
When you use OS/VS COBOL with Enterprise COBOL, there are differences in support
between non-CICS and CICS:
In a non-CICS environment
You can make static and dynamic calls between Enterprise COBOL and other
COBOL programs.
In a CICS environment
You cannot call OS/VS COBOL programs in the CICS environment. You must
use EXEC CICS LINK to transfer control between OS/VS COBOL programs and
other COBOL programs.
Calls to dynamic link libraries (DLLs) are an alternative to COBOL dynamic CALL, and
are well suited to object-oriented COBOL applications, UNIX programs, and
applications that interoperate with C/C++.
Under z/OS, linking two load modules together results logically in a single program
with a primary entry point and an alternate entry point, each with its own name.
Each name by which a subprogram is to be dynamically called must be known to the
system. You must specify each such name in linkage-editor or binder control
statements as either a NAME or an ALIAS of the load module that contains the
subprogram.
With static calls statement, the COBOL program and all called programs are part of
the same load module. When control is transferred, the called program already
resides in storage, and a branch to it takes place. Subsequent executions of the CALL
statement make the called program available in its last-used state unless the called
program has the INITIAL attribute. In that case, the called program and each
program directly or indirectly contained within it are placed into their initial state
each time the called program is called within a run unit.
If you specify alternate entry points, a static CALL statement can use any alternate
entry point to enter the called subprogram.
In these forms of the CALL statement, the called COBOL subprogram is not link-
edited with the main program. Instead, it is link-edited into a separate load module,
and is loaded at run time only when it is required (that is, when called). The
program-name in the PROGRAM-ID paragraph or ENTRY statement must be identical to
the corresponding load module name or load module alias of the load module that
contains the program.
Each subprogram that you call with a dynamic CALL statement can be part of a
different load module that is a member of either the system link library or a private
library that you supply. In either case it must be in an MVS load library; it cannot
reside in the hierarchical file system. When a dynamic CALL statement calls a
subprogram that is not resident in storage, the subprogram is loaded from secondary
storage into the region or partition that contains the main program, and a branch to
the subprogram is performed.
The first dynamic call to a subprogram within a run unit obtains a fresh copy of the
subprogram. Subsequent calls to the same subprogram (by either the original caller
or any other subprogram within the same run unit) result in a branch to the same
copy of the subprogram in its last-used state, provided the subprogram does not
possess the INITIAL attribute. Therefore, the reinitialization of either of the following
items is your responsibility:
If you call the same COBOL program in different run units, a separate copy of
WORKING-STORAGE is allocated for each run unit.
The operating system provides facilities for creating and using dynamically linked
shared libraries. With dynamic linking, external symbols referenced in user code and
defined in a shared library are resolved by the loader at load time. When you compile
a program that uses shared libraries, they are dynamically linked to your program by
default.
The idea behind shared libraries is to have only one copy of commonly used routines
and to maintain this common copy in a unique shared-library segment. These
common routines can significantly reduce the size of executable programs, thereby
saving disk space.
You can reduce the size of your programs by using dynamic linking, but there is
usually a trade-off in performance. The shared library code is not present in the
executable image on disk, but is kept in a separate library file. Shared code is loaded
into memory once in the shared library segment and shared by all processes that
reference it. Dynamically linked libraries therefore reduce the amount of virtual
storage used by your program, provided that several concurrently running
applications (or copies of the same application) use the procedures provided in the
shared library. They also reduce the amount of disk space required for your program
provided that several different applications stored on a given system share a library.
Other advantages of shared libraries are as follows:
• Load time might be reduced because the shared library code might already be
in memory.
• The routines are not statically bound to the application but are dynamically
bound when the application is loaded. This permits applications to automatically
inherit changes to the shared libraries, without recompiling or rebinding.
The cc command defaults to the shared-library option. To override the default, when
you compile your programs to create statically-linked object files, use the -bnso
option as follows:
This option forces the linker to place the library procedures your program references
into the program's object file. The /lib/syscalIs.exp file contains the names of
system routines that must be imported to your program from the system. This file
must be specified for static linking. The routines that it names are imported
automatically by libc.a for dynamic linking, so you do not need to specify this file
during dynamic linking. For further details on these options, see Efficient use of the
ld command and the Id command.