I would like to call C routines from Fortran under linux as suggested in
section 5.6 of
the "Writing R extensions" documentation.
I'm familiar with Fortran but not with C.
I understand the example provided in Fortran:
subroutine testit()
double precision normrnd, x
call rndstart()
x = normrnd()
call dblepr("X was", 5, x, 1)
call rndend()
end
but I don't understand the purpose of this C wrapper:
#include <R.h>
void F77_SUB(rndstart)(void) { GetRNGstate(); }
void F77_SUB(rndend)(void) { PutRNGstate(); }
double F77_SUB(normrnd)(void) { return norm_rand(); }
neither how I should compile it.
Could anyone explain how I should compile and link
the C and Fortran files above, and call the Fortran subroutine from R.
Thanks,
Gilles
The C wrappers are there to align the linking conventions expected by the
Fortran compiler (usually subroutine/function foo has its entry point in the
object file indicated by a symbol foo_, but it depends on the platform) to
that of the C compiler. (The C compiler just uses the function name.) The
wrappers give C functions named whatever is appropriate (eg "foo_") to
get
an entry point that "call foo" will trigger linking to.
Calling the Fortran subroutine from R is via .Fortran() after doing a
dyn.load() of the shared object file. Creating the shared object should just
be a matter of R CMD SHLIB file1.c file2.f but I've never tried using
Fortran and C together. Take a look at the magic built in to the R CMD SHLIB
and R CMD COMPILE commands, and at some of the packages that come with R (I
just do a "find" for "*.f" in the src tree) if you need
examples, eg.
src/library/stats.
Reid Huntsinger
-----Original Message-----
From: r-devel-bounces at r-project.org [mailto:r-devel-bounces at r-project.org]
On Behalf Of Gilles GUILLOT
Sent: Tuesday, June 14, 2005 1:05 PM
To: R-devel at stat.math.ethz.ch
Subject: [Rd] Calling C from Fortran
I would like to call C routines from Fortran under linux as suggested in
section 5.6 of
the "Writing R extensions" documentation.
I'm familiar with Fortran but not with C.
I understand the example provided in Fortran:
subroutine testit()
double precision normrnd, x
call rndstart()
x = normrnd()
call dblepr("X was", 5, x, 1)
call rndend()
end
but I don't understand the purpose of this C wrapper:
#include <R.h>
void F77_SUB(rndstart)(void) { GetRNGstate(); }
void F77_SUB(rndend)(void) { PutRNGstate(); }
double F77_SUB(normrnd)(void) { return norm_rand(); }
neither how I should compile it.
Could anyone explain how I should compile and link
the C and Fortran files above, and call the Fortran subroutine from R.
Thanks,
Gilles
______________________________________________
R-devel at r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Thanks for your reply.
Am I write if I say that the wrapper shoul be
double F77_SUB(mygammafn)(double *x) { return gammafn(*x); }
instead of
double F77_SUB(mygammafn)(double *x) { return gammafn(x); }
the first does not compile.
wrapper2.c: In function `mygammafn_':
wrapper2.c:6: error: incompatible type for argument 1 of `Rf_gammafn'
The second compiles and works fine.
But still, I find it very strange as the C function gammafn actually called
( as I can see from /R-2.1.0/src/nmath/gamma.c)
is not defined as
double gammafn(double *x)
but as
double gammafn(double x)
Am I missing something ?
Gilles
Le Mercredi 15 Juin 2005 17:06, vous avez ?crit :> I actually deleted a part of my reply, dealing with exactly that. Sorry!
> You need to declare the C wrapper to take a pointer to a double
("double
> *") rather than a double. C passes by value whereas Fortran passes by
> reference; in C you get this effect by passing a pointer to the value
> (which is also a value). So you want
>
> double F77_SUB(mygammafn)(double *x) { return gammafn(x); }
>
> That should work; if not let me know and I'll look more carefully at
> Fortran <-> C conventions.
>
> Reid Huntsinger
>
> -----Original Message-----
> From: Gilles GUILLOT [mailto:gilles.guillot at inapg.inra.fr]
> Sent: Wednesday, June 15, 2005 3:50 AM
> To: Huntsinger, Reid
> Subject: Re: [Rd] Calling C from Fortran
>
>
> Thanks Reid!
> And now if I want to call a C function with arguments,
> e.g. to compute the gamma function at x,
> my C wrapper is:
>
> #include <R.h>
> #include <Rmath.h>
> void F77_SUB(rndstart)(void) { GetRNGstate(); }
> void F77_SUB(rndend)(void) { PutRNGstate(); }
> double F77_SUB(normrnd)(void) { return norm_rand(); }
> double F77_SUB(mygammafn)(double x) { return gammafn(x); }
>
> And my Fortran is:
> subroutine testit()
> implicit none
> double precision normrnd, x, y, mygammafn
> call rndstart()
> x = dabs(normrnd())
> write(*,*) 'x=',x
> call rndend()
>
> y = mygammafn(x)
> write(*,*) 'y=',y
> end
>
> And it does not work, all calls of testit return the same y value.
> What is incorrect in my files ?
>
>
> Gilles
>
>
>
>
>
> ---------------------------------------------------------------------------
>--- Notice: This e-mail message, together with any attachments, contains
> information of Merck & Co., Inc. (One Merck Drive, Whitehouse Station,
New
> Jersey, USA 08889), and/or its affiliates (which may be known outside the
> United States as Merck Frosst, Merck Sharp & Dohme or MSD and in Japan,
as
> Banyu) that may be confidential, proprietary copyrighted and/or legally
> privileged. It is intended solely for the use of the individual or entity
> named on this message. If you are not the intended recipient, and have
> received this message in error, please notify us immediately by reply
> e-mail and then delete it from your system.
> ---------------------------------------------------------------------------
>---
--
_________________________________________________________________________
Gilles GUILLOT
INRA -D?partement Math?matiques et Informatique Appliqu?es
Unit? Mixte de Recherche INRA - INAPG - ENGREF
Institut National Agronomique de Paris-Grignon
16, rue Claude Bernard
75231 Paris cedex 5 France
phone 33 1 44 08 18 42
fax 33 1 44 08 16 66
http://www.inapg.fr/ens_rech/mathinfo/personnel/guillot/welcome.html
(Forgot to post.) Yes, that was a typo, and the reason is the same; the C
function expects a value rather than its address. That's why you can't
use
it directly from Fortran (aside from naming issues) but it's fine in C.
Reid Huntsinger
-----Original Message-----
From: Gilles GUILLOT [mailto:gilles.guillot at inapg.inra.fr]
Sent: Wednesday, June 15, 2005 11:50 AM
To: R-devel at lists.R-project.org
Cc: Huntsinger, Reid
Subject: Re: [Rd] Calling C from Fortran
Thanks for your reply.
Am I write if I say that the wrapper shoul be
double F77_SUB(mygammafn)(double *x) { return gammafn(*x); }
instead of
double F77_SUB(mygammafn)(double *x) { return gammafn(x); }
the first does not compile.
wrapper2.c: In function `mygammafn_':
wrapper2.c:6: error: incompatible type for argument 1 of `Rf_gammafn'
The second compiles and works fine.
But still, I find it very strange as the C function gammafn actually called
( as I can see from /R-2.1.0/src/nmath/gamma.c)
is not defined as
double gammafn(double *x)
but as
double gammafn(double x)
Am I missing something ?
Gilles
Le Mercredi 15 Juin 2005 17:06, vous avez ?crit :> I actually deleted a part of my reply, dealing with exactly that. Sorry!
> You need to declare the C wrapper to take a pointer to a double
("double
> *") rather than a double. C passes by value whereas Fortran passes by
> reference; in C you get this effect by passing a pointer to the value
> (which is also a value). So you want
>
> double F77_SUB(mygammafn)(double *x) { return gammafn(x); }
>
> That should work; if not let me know and I'll look more carefully at
> Fortran <-> C conventions.
>
> Reid Huntsinger
>
> -----Original Message-----
> From: Gilles GUILLOT [mailto:gilles.guillot at inapg.inra.fr]
> Sent: Wednesday, June 15, 2005 3:50 AM
> To: Huntsinger, Reid
> Subject: Re: [Rd] Calling C from Fortran
>
>
> Thanks Reid!
> And now if I want to call a C function with arguments,
> e.g. to compute the gamma function at x,
> my C wrapper is:
>
> #include <R.h>
> #include <Rmath.h>
> void F77_SUB(rndstart)(void) { GetRNGstate(); }
> void F77_SUB(rndend)(void) { PutRNGstate(); }
> double F77_SUB(normrnd)(void) { return norm_rand(); }
> double F77_SUB(mygammafn)(double x) { return gammafn(x); }
>
> And my Fortran is:
> subroutine testit()
> implicit none
> double precision normrnd, x, y, mygammafn
> call rndstart()
> x = dabs(normrnd())
> write(*,*) 'x=',x
> call rndend()
>
> y = mygammafn(x)
> write(*,*) 'y=',y
> end
>
> And it does not work, all calls of testit return the same y value.
> What is incorrect in my files ?
>
>
> Gilles
>
>
>
>
>
>
--------------------------------------------------------------------------->--- Notice: This e-mail message, together with any attachments, contains
> information of Merck & Co., Inc. (One Merck Drive, Whitehouse Station,
New
> Jersey, USA 08889), and/or its affiliates (which may be known outside the
> United States as Merck Frosst, Merck Sharp & Dohme or MSD and in Japan,
as
> Banyu) that may be confidential, proprietary copyrighted and/or legally
> privileged. It is intended solely for the use of the individual or entity
> named on this message. If you are not the intended recipient, and have
> received this message in error, please notify us immediately by reply
> e-mail and then delete it from your system.
>
--------------------------------------------------------------------------->---
--
_________________________________________________________________________
Gilles GUILLOT
INRA -D?partement Math?matiques et Informatique Appliqu?es
Unit? Mixte de Recherche INRA - INAPG - ENGREF
Institut National Agronomique de Paris-Grignon
16, rue Claude Bernard
75231 Paris cedex 5 France
phone 33 1 44 08 18 42
fax 33 1 44 08 16 66
http://www.inapg.fr/ens_rech/mathinfo/personnel/guillot/welcome.html