[R] Calling Fortran from R: Issues with dynamic loading of fortran dll
Duncan Murdoch
murdoch.duncan at gmail.com
Mon Jan 16 19:09:37 CET 2012
The problem is your path. You are finding a 64 bit compiler first, so
you get a 64 bit dll.
The path I use has these components in this order (as recommended in our
docs, and as set by the Rtools installer):
Rtools/bin
Rtools/perl/bin
Rtools/MinGW/bin # NOT MinGW64/bin as you had
<other stuff, including R 2.14.1/bin/i386>
So the error message was likely correct: your compiler wasn't producing
a Win32 DLL, it was producing a Win64 DLL.
Duncan Murdoch
On 16/01/2012 11:34 AM, David Stevens wrote:
> I'm a little worried this is getting off track. I'll recap
>
> 1. I'm using R 2.14.1 from CRAN - installed last week in d:\program
> files\R\R-2.14.1 using the Windows installer
> 2. I've just installed Rtools 15.1 this morning in d:\Rtools at Duncan's
> recommendation using the Rtools Windows installer
> 3. my folder is "d:\fortran folders\fortran multiresponse"
> 4. my file is "foo.f"
> 5. from the command line I navigate to my folder where foo.f is located
> 6. from the command line I type "set CYGWIN=nodosfilewarning"
> 7. from the command line I then type "R CMD SHLIB foo.f" and get
> gcc -shared -s -static-libgcc -o foo.dll tmp.def foo.o
> -Ld:/RCompile/CRANpkg/extralibs/local/lib/i386
> -Ld:/RCompile/CRANpkg/extralibs/local/lib -lgfortran
> -Ld:/PROGRA~1/r/R-214~1.1/bin/i386 -lR
> 8. I check the directory and find a newly created foo.dll
> 9. from the command line I type 'rgui' (w/o the quotes) and an R console
> opens with V 14.1 on the masthead
> 10. In R, I check the path with getwd() and find my path "d:\fortran
> folders\fortran multiresponse"
> 11. then from the R gui dyn.load("foo.dll")yields
>
> Error in inDL(x, as.logical(local), as.logical(now), ...) :
> unable to load shared object 'd:/Fortran folders/Fortran
> Multiresponse/foo.dll':
> LoadLibrary failure: *%1 is not a valid Win32 application*.
>
> 12. To make sure that the proper file is being found, from the command
> line I delete foo.dll and try again
>
> > dyn.load("foo.dll")
>
> Error in inDL(x, as.logical(local), as.logical(now), ...) :
> unable to load shared object 'd:/Fortran folders/Fortran
> Multiresponse/foo.dll':
> LoadLibrary failure: *The specified module could not be found*.
>
> 13. I then recreate foo.dll as above and try to load
>
> Errorin inDL(x, as.logical(local), as.logical(now), ...) :
> unable to load shared object 'd:/Fortran folders/Fortran
> Multiresponse/foo.dll':
> LoadLibrary failure: *%1 is not a valid Win32 application*.
> nd.
>
> 14. So, I try to build the dll from R
>
> system("R CMD SHLIB foo.f")
>
> x86_64-w64-mingw32-gcc -shared -s -static-libgcc -o foo.dll tmp.def
> foo.o -Ld:/RCompile/CRANpkg/extralibs64/local/lib/x64
> -Ld:/RCompile/CRANpkg/extralibs64/local/lib -lgfortran
> -LD:/PROGRA~1/R/R-214~1.1/bin/x64 -lR
> d:/rtools/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.5.2/../../../../x86_64-w64-mingw32/bin/ld.exe:
> i386 architecture of input file `foo.o' is incompatible with i386:x86-64
> output
> foo.o:foo.f:(.text+0x44): undefined reference to `__gfortran_st_write'
> foo.o:foo.f:(.text+0x58): undefined reference to `__gfortran_transfer_real'
> foo.o:foo.f:(.text+0x60): undefined reference to `__gfortran_st_write_done'
> collect2: ld returned 1 exit status
>
> 15. No good, so I check the path
> PATH=...;d:\program
> files\r\r-2.14.1\bin;D:\Rtools\bin;D:\Rtools\perl\bin;D:\Rtools\MinGW64\bin;D:\Program
> files\R\R-2.14.1\bin\x64;
>
> 16. Going back to compiling from the command line, it appears to me that
> the Rtools compiler (I assume that's what's used with the R CMD SHLIB
> command) is delivering an incompatible dll.
>
> Shall I delete everything, reinstall, and try again?
>
> BTW, I've successfully used .Fortran on previous versions of R and
> plain vanilla gfortran (from gcc) on an older winxp32 machine using
> fairly sophisticated fortran 95 code, with modules, structures, etc, so
> I'm not a complete babe-in-the-woods (though apparently I'm back to
> being that). That said there is much I don't know especially about
> differences between 32- and 64-bit code that comes from the compilers
> and interfaces between R and shared libraries
>
> Any and all help is appreciated!
>
> David
>
> On 1/16/2012 7:37 AM, Duncan Murdoch wrote:
> > On 16/01/2012 8:55 AM, David Stevens wrote:
> >> I installed RTools - though I'm unable to use it within R, from the
> >> command prompt the file will compile and create the foo.dll using R CMD
> >> SHLIB foo.f. I simlified to code for fortran IV (?really) compliance
> >>
> >> foo.f:
> >>
> >> Subroutine foo(x)
> >> real x
> >> x = x + 2.
> >> return
> >> end
> >>
> >> R CMD SHLIB foo.f
> >> cygwin warning:
> >> MS-DOS style path detected:
> >> d:/PROGRA~1/r/R-214~1.1/etc/i386/Makeconf
> >> Preferred POSIX equivalent is:
> >> /cygdrive/d/PROGRA~1/r/R-214~1.1/etc/i386/Makeconf
> >> CYGWIN environment variable option "nodosfilewarning" turns off this
> >> warning.
> >> Consult the user's guide for more details about POSIX paths:
> >> http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
> >> gfortran -O3 -mtune=core2 -c foo.f -o foo.o
> >> gcc -shared -s -static-libgcc -o foo.dll tmp.def foo.o
> >> -Ld:/RCompile/CRANpkg/extralibs/local/lib/i386
> >> -Ld:/RCompile/CRANpkg/extralibs/local/lib -lgfortran
> >> -Ld:/PROGRA~1/r/R-214~1.1/bin/i386 -lR
> >>
> >> Now the issue is getting it to dyn.load("foo.dll"). I'm greeted with
> >>
> >> Error in inDL(x, as.logical(local), as.logical(now), ...) :
> >> unable to load shared object 'd:/Fortran folders/Fortran
> >> Multiresponse/foo.dll':
> >> LoadLibrary failure: %1 is not a valid Win32 application.
> >>
> >> Any thoughts?
> >
> > It worked for me. That is, I created the foo.f file, then ran
> >
> > R CMD SHLIB foo.f
> >
> > from the command line, then rgui on the command line. Once in R I ran
> >
> > dyn.load("foo.dll")
> >
> > and it worked without a complaint on my system. I would guess the
> > differences are:
> >
> > 1. I have the stupid "nodosfilewarning" set to keep Cygwin programs
> > quiet:
> >
> > set CYGWIN=nodosfilewarning
> >
> > 2. I ran rgui from the command line. That means I got it from the
> > same path where R was found in the R CMD SHLIB call. You might have
> > run a different version, or might have been in a different directory,
> > trying to load some other "foo.dll" if you started rgui in some other
> > way.
> >
> > Duncan Murdoch
> >
> >> David S
> >>
> >> On 1/15/2012 5:09 PM, Duncan Murdoch wrote:
> >> > On 12-01-15 5:34 PM, David Stevens wrote:
> >> >> I successfully used .Fortran to load and execute my fortran
> >> procedures
> >> >> under WinXP and 32 bit R. Alas, the same isn't true with my next
> >> Windows
> >> >> 7/64 machine, R 2.14.1 (64 bit) and the gnu gfortran (64) compiler
> >> >> (mingw64 v. 4.6.1). Though I'm able to compile the routines from the
> >> >> command line using gfortran '...', .Fortran('foo2') results in an
> >> error
> >> >> saying the Fortran symbol name "foo2" not in load table.
> >> >>
> >> >> foo.f90:
> >> >>
> >> >> Module foo
> >> >> contains
> >> >> Subroutine foo2(x)
> >> >>
> >> >> real(kind=8),intent(inout) :: x
> >> >> x = x + 2
> >> >>
> >> >> end subroutine foo2
> >> >>
> >> >> end module foo
> >> >>
> >> >> c:\mingw64\bin\gfortran --shared -Wall -pedantic -g -o foo.dll
> >> foo.f90
> >> >>
> >> >> ff = "d:/Fortran folders/Fortran Multiresponse/foo.dll"
> >> >> x= dyn.load(ff)
> >> >> .Fortran('foo2',as.double(1))
> >> >>
> >> >> Error in .Fortran("foo", as.double(1)) :
> >> >> Fortran symbol name "foo" not in load table
> >> >>
> >> >> Can someone point me in the direction of a solution?
> >> >
> >> > Some or all of these might help:
> >> >
> >> > 1. Get R to do the compiling for you: it knows the compiler
> >> > arguments that produce compatible code. (Use R CMD shlib for this.)
> >> >
> >> > 2. Use a compiler supplied with the Rtools collection.
> >> >
> >> > 3. Find out what name got exported, and use .C instead of
> >> .Fortran to
> >> > call that.
> >> >
> >> > Duncan Murdoch
> >>
> >
>
More information about the R-help
mailing list