Compaq (Digital) Visual Fortran
Compaq's Visual Fortran compiler (CVF) offers a great deal of flexibility to create DLLs callable from C and/or Visual Basic. The compiler has a good set of options to modify name-mangling, calling conventions and the method used to pass arguments. Most of these options can be indicated through the use of compiler directives (or pragmas) embedded in the source code. CVF compiler directives are defined as comment lines, starting with DEC$.
To indicate that a subroutine should conform to the standard calling convention, you add the DEC$ATTRIBUTE STDCALL compiler directive to the declaration of the subroutine. For example:
subroutine MySub(argument1, argument2)
!DEC$ATTRIBUTES STDCALL:: GenDNASequence
In Compaq Visual Fortran, adding the STDCALL attribute also changes the default method used to pass arguments, so you need to tell the compiler that arguments to subroutine MySub are passed by reference. You can do this with the DEC$ATTRIBUTE REFERENCE directive:
subroutine MySub(argument1, argument2)
!DEC$ATTRIBUTES STDCALL:: MySub
!DEC$ATTRIBUTES REFERENCE:: argument1, argument2
Also, when a procedure is declared with the standard calling convention (STDCALL), Compaq Visual Fortran mangles its name. The name-mangling performed by CVF converts the name of the procedure to all uppercase, adds an underscore as a prefix to the name, and appends an at symbol (@) followed by the size of the stack (in bytes) at the end of the name. The size of the stack is equal to 4 times the number of arguments in the subroutine. MySub has 2 arguments, so the mangled name will be:
_MYSUB@8
Having to use this name to call our DLL procedure would be awful in most languages, and illegal in Visual Basic. You can use another DEC$ATTRIBUTES compiler directive to indicate an alias for the mangled name of the exported subroutine:
!DEC$ATTRIBUTES ALIAS: 'MySub'::MySub
The first argument is the alias (i.e. the name by which the subroutine would be available to external programs using the DLL), the second argument is the Fortran name of the subroutine.
Finally, to indicate that the subroutine must be exported to the DLL as a public procedure, you add the DEC$ATTRIBUTES DLLEXPORT compiler directive to the body of the subroutine:
!DEC$ATTRIBUTES DLLEXPORT:: MySub
So the full declaration of MySub would look like this:
subroutine MySub(argument1, argument2)
!DEC$ATTRIBUTES STDCALL:: MySub
!DEC$ATTRIBUTES DLLEXPORT:: MySub
!DEC$ATTRIBUTES ALIAS: 'MySub'::MySub
!DEC$ATTRIBUTES REFERENCE:: argument1, argument2
To create a DLL, you compile and link using the /dll switch. The following command-line would compile and link MySub.f90 (containing subroutine MySub) into MySub.dll:
f90 MySub.f90 /dll /out:MySub.dll