Building and Using DLLs
Building and Using DLLs
Windows based computers support two types of libraries: static and dynamic. A static
library is a collection of object files (modules), each containing one or more routines that
are maintained in a single file — a library. When a library file is presented to the linker,
modules that are required to satisfy unresolved external references are selected for
inclusion into the application file. The advantage of a library is that only those modules
that are required to satisfy unresolved external references are linked into the application.
The Absoft FORTRAN runtime math library, af77math.lib, is an example of a static
library. Not every FORTRAN program requires a hyperbolic tangent function, so it is
only linked into those programs that require it.
A dynamic load library (DLL) is similar to a static library in that it contains a collection
of routines in object modules. The difference is that the elements of the library are not
linked into the final application file, but rather are available for linking when the
application is executed. The advantage to this type of library is that the individual
applications can be smaller and several applications can share the same library. It is also
the only mechanism available to certain applications to reference functions or routines
written in FORTRAN or C. The disadvantage is that the dynamic or shared library must
be available on every computer where the application is to be run.
To build a DLL from the command prompt, add –dll to your compile command(s).
Obviously, the two mechanisms cannot be intermixed and passing too many or two few
arguments with the STDCALL protocol is disastrous (the wrong number of arguments
will be removed from the stack by the callee). As a protection against this, STDCALL
function names in the object code are often mangled by appending a commercial at sign
(‘@’) and the size of the stack (in bytes) to the function name. In this way, the caller and
the callee must agree on the number of arguments, or the program will not link.
The Absoft runtime libraries (math and I/O) can be statically linked to the DLL; that is
included in the DLL itself, or they can be referenced as separate DLLs. The advantage to
statically linking them is that the DLL will be stand-alone; it will not need to have the
math and I/O DLL libraries present at runtime. However, if your main program and your
DLL are designed to perform I/O to the same unit number, the DLL versions of the
runtime libraries must be used so that the main program and its subroutines will share I/O
memory.
Sharing memory between DLLs is possible using COMMON blocks. One DLL must
declare the common block with the normal COMMON declaration. The DLLs sharing
the common block replace the COMMON declaration with the keyword GLOBAL. The
compiler option –YMSFT_GLB_PFX must be used to set up the shared memory section.
• For 32-bit DLLs, Visual Basic must know to look for the STDCALL mangled
name. For 64-bit code, the name is not mangled.
• Visual Basic must be able to find the required DLL when the routine is called.
These requirements are met by providing Visual Basic with a declaration (or prototype)
of the subroutine in the DLL. The follow code illustrates a declaration for a simple
Fortran routine named CALCULATE which accepts four arguments and is located in a
DLL named CALCULATE.dll.
A corresponding FORTRAN routine which simply adds the first three arguments and
places the result in the fourth argument is listed below.
For example, a Fortran program linked against the DLL versions of the Absoft runtime
libraries (af77mathdll.dll, af90mathdll.dll, and afiodll.dll) will execute successfully when
run inside an Absoft Development Command Prompt because the PATH variable is
automatically set to include the location of the Absoft DLLs. However, this same
program will not run from a generic Windows command prompt session on the same
computer or another computer because the path to the Absoft DLLs is not established.
DLLs must be placed in directory on the system where the program can find them when it
is executed. The Windows DLL search paths are:
1. The directory where the executable module for the current process is located.
Debugging a DLL
The easiest way to debug a DLL is to add a simple main program unit which calls the
DLL's subroutines. This allows you to build a single executable file and debug it with
Fx3. In this way, loading and interfacing issues will be avoided until after the procedure
logic has been proven. It is also possible to debug the code when it is built as a DLL. If
the DLL will ultimately be called from an executable program which is not written in
FORTRAN, you may still want to write a simple main program which links against the
DLL to avoid loading and interfacing issues.
1. The executable program will still need to be able to find the DLLs when run
under the debugger. The same search paths described in the section on executing a
program which uses DLLs apply. When running under the debugger, a program
which is unable to locate a required DLL will stop executing and a debugger will
display the message "Stopped on Unable To Locate Required DLL".
2. When debugging a program which makes use of DLLs, the Fx3 debugger will
look for a DLL's symbol file (.pdb file) in the directory where the DLL was
loaded and in the directory which contains the executable program.
3. If the source code which produced the DLL is not in the directory where the DLL
is located or in the directory which contains the executable program, you may
need to add additional source paths to assist the debugger in locating the source
code if the debugger is unable to determine the location from the information in
the symbol file.