Creating a Windows DLL with Visual Fortran

First, examine your Fortran code. Fortran I/O statements (and possibly other non-numeric routines) can mess up the runtime environment of many programs that will link to the DLL. I can't remember the problems, but I also gave up using Fortran functions and returning function values. I do every routine as a Fortran subroutine, passing both input variables and output results as variables. As always, try to vectorize things if you want a nice S-Plus routine.

Start a new project within Visual Fortran (MS) IDE and select the type as "Fortran Dynamic Link Library".

Open the fortran source file. For each routine that you want to have available in the DLL, you need to add a "comment line", starting in column 1, as in the following example:

    subroutine mysub1(a,b)
cDEC$ ATTRIBUTES DLLEXPORT :: MYSUB1
    ...
    subroutine mysub2(a,b)
cDEC$ ATTRIBUTES DLLEXPORT :: MYSUB2

This is Compaq Fortran's way of telling the compiler to create an external "entry point" for MYSUB1, etc. (Each routine needs this kind of line, with it's name after the "::". If you don't put this line there, a routine will not be visible in the DLL. It can be used inside your Fortran program, but will not be available for an external program to call.)

Build the DLL within the IDE, say nolan.dll.



Linking a DLL to S-Plus under Windows


Use the IDE editor or some editor to create a file, say "c:\folder\nolan.s", like the following: ("c:\folder" should be the folder/directory where you put this stuff. Also note that S-Plus uses the "\" key as an escape key, so don't use it in a filename, use "/".)

# S-Plus code to link to Fortran DLL
dll.load( "c:/folder/nolan.dll",c("MYSUB1","MYSUB2"))

# function definitions
mysub1 <- function(a,b)
{ r <-.Fortran("MYSUB1", as.double(a),as.double(b))
    r}
mysub2 <- function(a,b)
{ r <- .Fortran("MYSUB2", as.double(a),as.double(b))
    r}

This tells S-plus to load the dll, make the entry points MYSUB1 and MYSUB2 available to S-plus, and tells S-Plus what variables to pass. The statements above return a record r, with all the information about the call. In most cases, you only want to return part of the record, say r$a to return the contents of variable a.

Start S-Plus, then type source("c:/folder/nolan.s"). This will read the file created above and define the entry points. You must do this every time you start the program. When you call mysub1(a,b), S-plus will attempt to call the dll and execute it's code. If you have the wrong number of arguments, or some other specifiation error, S-Plus may blow up.




There are more advanced things you can do, e.g. chapters, but this should get you started. Good luck!

Bohdan Zograf has provided a Belorussian translation of this page.