Static CALLs
In COBOL, you normally call a subroutine
like this:CALL 'A' USING arguments
The static form of the CALL statement
specifies the name of the subroutine as a literal; e.g., it is in quotes.
This is the static form of a subroutine
call. The compiler generates object code
for this which will cause the linker to copy the object module a.obj into your
executable when it is linked.
In the static CALL
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 its initial state every time the called program is
called within a run unit.
So, if you modify "A" and
recompile it, you must also relink all of the executables that call
"A", because the each of the executables contains its own copy of
"A".
Good Things About Static CALLs
Fewer files are needed to distribute your
application because your application can be built into a single EXE file, or
perhaps an EXE for your main, and a couple of DLLs for subordinate
modules. This generally makes it simpler
to distribute and/or upgrade your end users.
No risk of mixing/matching different
versions of your called subroutines, because they are bundled into your main
program.
Bad Things About Static CALLs
You must relink all of the EXE and DLL
files in your application that use a statically linked subroutine in order to
use the newer version of the subroutine.
If your application contains DLLs that call
a subroutine statically, each DLL will have its own copy of the subroutine,
including the storage defined in the subroutine. As a result, your application uses more
storage than necessary.
If your application has multiple DLLs that
use the same statically named subroutine, each DLL has its own copy of that
subroutine and its storage. Therefore,
if you set a value in the subroutine in one of the DLLs, it's local to that
DLL. The copy linked to the other DLLs
will not know about this. This can be
either a Good Thing or a Bad Thing, of course, but it's definitely a trap for
the unwary.
Dynamic CALLs
In COBOL, the dynamic form of a subroutine
call is coded like this:
01 SUBROUTINE-A
PIC X(8) VALUE 'A'.
CALL SUBROUTINE-A USING arguments
The dynamic form of the CALL statement
specifies the name of the subroutine using a variable; the variable contains
the name of the subroutine to be invoked.
The difference is that the name of the
subroutine is found in the variable SUBROUTINE-A. The compiled code will cause the operating
system to load the subroutine when it is required instead of incorporating it
into the executable..
In this form of
the CALL statement, the called COBOL subprogram is not link-edited with the
main program, but is instead link-edited into a separate load module, and is
loaded at run time only when it is required (that is, when called).
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 containing 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 under different run units, a separate copy of working
storage is allocated for each run unit.
Note that you can also load a module
dynamically by including it in a DLL and then linking it using the import
library for that DLL!
Good Things About Dynamic CALLs
You don't need to relink your application
if you change something in your subroutine; only the subroutine DLL needs to be
relinked.
All executables that call this subroutine
will share the same DLL; both the code and data. Since your application only loads one copy of
a dynamically called subroutine, it uses less memory.
Changes in values contained within the
dynamically called subroutine are available to all the DLLs that use it,
because they all share the same copy of the subroutine.
You can free memory that a dynamically
called subroutine was using by CANCELing the subroutine. This is, however, not generally of much use
in the 32-bit Windows virtual-memory environment, since Windows will 'page out'
inactive data from the computer's real memory pool anyway.
Bad Things About Dynamic CALLs
Every dynamically called subroutine must be
linked as a DLL (unless you use an import library to expose other entry points
in a DLL). Therefore, if you application consists of hundreds of subroutines
and they're all called dynamically, you will need to distribute hundreds of DLLs.
It's possible to mix versions of your
DLLs. This can be a problem both with
distributing your application and with end-users installing updates improperly.
If one of your DLLs is missing, you may not
know about it until the user exercises some facility that tries to call that
DLL. At that point, your application
will terminate abnormally unless you handle this situation.
If you CALL a DLL, CANCEL it, then CALL it
again, you incur more I/O because the routine needs to be reloaded if you
CANCEL it. This can slow down an
application because it requires more disk activity. Again, in the Windows environment this is
usually unnecessary because Windows does an excellent job of managing memory.
If you mix and match static and dynamic
calls to the same subroutine, your software might have several different
versions in memory at once. Guess how
much fun it will be trying to debug THAT mess?
Which is better, Static or Dynamic
CALLs?
The answer is, it depends.
Static subroutines are nice, because your
application can be built into a single EXE file, or perhaps an EXE for your
main, and a couple of DLLs for subordinate modules.
Dynamic subroutines are nice because you
can manage memory differently and you can update a portion of your application
by shipping a newer DLL instead of the entire application.
You really need to consider the pros and
cons and how they affect your own application.
For what it's worth, though, we favor using a minimum of executable
modules because it reduces headaches with mismatched or lost pieces of an
application.
No comments:
Post a Comment