Using Fortran with R in Windows

General instructions for working with Fortran are in the Writing R Extensions manual in the docs subdirectory of the R installation. Instructions that work with the g77 compiler are given in the readme.packages file in the src/gnuwin32 subdirectory; some additional tips are given below.

Contents

Back to main list

Compaq Visual Fortran v. 6.1


These notes were written by Martyn Byng.

To solve the problem I basically created the DLL as a fortran dynamic linked library project, and added the two `!DEC' commands to the subroutine I wished to add to the DLL. The first (DLLEXPORT), just informs the compiler to export that routine to the DLL, the second defines the calling convention (C => cdecl) and adds an underscore to the routine name after it has been exported (the ALIAS command).

  SUBROUTINE ZTEST(A,B,C,D,E,F,G)
  !DEC$ ATTRIBUTES DLLEXPORT :: ZTEST
  !DEC$ ATTRIBUTES C, ALIAS:'ZTEST_' :: ZTEST

  INTEGER A,B,C,D,E,F,G	
  END

[Later...]
Having now tried this with a more complex routine, it appears that you also need to add the option REFERENCE to the !DEC commands, i.e. use
  !DEC$ ATTRIBUTES C, REFERENCE, ALIAS:'ZTEST_' :: ZTEST
instead of
  !DEC$ ATTRIBUTES C, ALIAS:'ZTEST_' :: ZTEST
if you wish to pass vectors to the routine.

Compaq Visual Fortran v. 6.6


These notes were written by J.R.M. Hosking, and modified with input from Dan Stram.

Using Fortran routines from R with CVF

1.  Take a working Fortran subroutine, and put its name in an ATTRIBUTES DLLEXPORT directive to ensure that the routine name is exported from the DLL that will be built.  Example:
SUBROUTINE MYSUB(X,N,XMEAN)
CDEC$ ATTRIBUTES DLLEXPORT,C,REFERENCE,ALIAS:'mysub_' :: MYSUB
   IMPLICIT DOUBLE PRECISION (A-H,O-Z)
   DOUBLE PRECISION X(N)
   XMEAN=0D0
   DO 10 J=1,N
   XMEAN=XMEAN+X(J)
  10 CONTINUE
   XMEAN=XMEAN/N
   RETURN
   END
The ALIAS:'mysub_' is needed because R expects that a routine name exported from a DLL will have an underscore appended to it, but CVF does not do this by default.

2. Compile and link the routine using the CVF option  /dll.  E.g., supposing that the routine is in a file rtest.f, at the command prompt type
df rtest.f /dll
This will create a file rtest.dll file that should be kept, and .obj, .lib and .exp files that are not needed for R and can be deleted.

3.  Now from an R command prompt, use dyn.load to load the DLL and .Fortan("mysub",...) to call the function.  Example:
 > dyn.load("E:\\rtest.dll")
> is.loaded(symbol.For("mysub")) [1] TRUE > x<-1:6 > .Fortran("mysub",as.double(x),as.integer(length(x)),xmean=double(1)) [[1]] [1] 1 2 3 4 5 6 [[2]] [1] 6 $xmean [1] 3.5 >
Note: Fortran 90 constructions can be used within the routine, e.g. the MYSUB routine could be written as
 Subroutine mysub(x,n,xmean)
 !DEC$ ATTRIBUTES DLLEXPORT,C,REFERENCE,ALIAS:'mysub_' :: MYSUB
 Implicit Double Precision (a-h,o-z)
 Double Precision x(n)
 xmean=Sum(x)/n
 Return
 End
... but Fortran 90 constructions involving the arguments will not work. E.g. this version will cause R (ver. 1.5.1) to crash:
 Subroutine mysub(x,xmean)
 !DEC$ ATTRIBUTES DLLEXPORT,C,REFERENCE,ALIAS:'mysub_' :: MYSUB
 Implicit Double Precision (a-h,o-z)
 Double Precision x(:)
 xmean=Sum(x)/Size(x)
 Return
 End 

g77 (gcc 3.2) compiler from MinGW


Some quick tips:

Last modified: $Date: 2004-12-07 14:24:26 -0500 (Tue, 07 Dec 2004) $, by Duncan Murdoch