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.

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 :: 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


2. Compile and link the routine using the CVF options /assume:underscore
and  /dll.  E.g., supposing that the routine is in a file rtest.f,
at the command prompt type


   df rtest.f /assume:underscore /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.

(/assume:underscore 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.)

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 :: 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 :: 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: April 24, 2003, by Duncan Murdoch