Static and Dynamic Subroutine CALLs
Keep in mind as you read this, that some compilers let you set options that
will override the calling mechanisms shown below. Therefore, even if your
program is coded to call a program statically, the compiler can convert it to
the dynamic form of CALL if you set (or don't set) the correct compiler options.
This is something to beware of, because it can cause problems for you if you
don't understand the issues.
Static CALLs
In COBOL, you normally call a subroutine like this:
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.
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..
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.
Dynamic CALLs via an Import Library
It's possible to create a DLL that contains many
subroutines, but which is accessed as though the subroutines are statically
linked. This is a very neat trick that uses the best features of static
and dynamic linking.
Related topics: