[R-pkg-devel] R_registerRoutines, etc.
Avraham Adler
avraham.adler at gmail.com
Sun Apr 23 04:47:06 CEST 2017
On Sat, Apr 22, 2017 at 6:13 PM, Rolf Turner <r.turner at auckland.ac.nz> wrote:
>
> The foregoing "official" way would seem to apply to functions called by
> ".Call" (which I never use; it is way over my head). What about functions
> called by ".Fortran()" or ".C()"?
>
>> | (b) For the sake of completeness, how *does* one replace the "void
>> *"
>> | constructions with "actual types" in a correct manner?
>> |
>> | Example: In my init.c file I currently have (as produced by
>> | package_native_routine_registration_skeleton()) :
>> |
>> | > extern void F77_NAME(mnnd)(void *, void *, void *, void *, void *);
>> |
>> | The code in mnnd.f reads:
>> |
>> | > subroutine mnnd(x,y,n,dminbig,dminav)
>> | > implicit double precision(a-h,o-z)
>> | > .....
>> |
>> | I.e. the "actual types are "double precision",
>> | "double precision", "integer", "double precision",
>> | "double precision".
>> |
>> | So in this case I should (?) replace
>> |
>> | > extern void F77_NAME(mnnd)(void *, void *, void *, void *, void *);
>> |
>> | by .... what? Can anyone tell me?
>>
>> No idea. I don't deal in Fortran. C++ is more than enough fun for me ;-)
>
>
> Well, C++ is too much for me. I find Fortran generally very easy. Be that
> as it were, are there any Fortran users out there who can answer my
> question, above?
>
I cannot answer your question completely, as I use .Call() to call
Fortran from R via C instead of using .Fortran—from what I have read
and researched, it is faster.
That being said, maybe this will help. Given a subroutine in Fortran
which starts like:
subroutine ddelap_f(x, nx, a, na, b, nb, l, nl, lg, pmfv) bind(C,
name="ddelap_f")
integer(kind = c_int), intent(in), value :: nx, na, nb, nl
! Sizes
real(kind = c_double), intent(in), dimension(nx) :: x
! Observations
real(kind = c_double), intent(out), dimension(nx):: pmfv
! Result
real(kind = c_double), intent(in) :: a(na), b(nb),
l(nl)! Parameters
integer(kind = c_int), intent(in) :: lg
! Log flag
integer :: i
! Integer
The corresponding C code which calls it is
void ddelap_f(double *x, int nx, double *a, int na, double *b, int
nb, double *l, int nl,
int *lg, double *ret);
and the actual code called by R is:
extern SEXP ddelap_C(SEXP x, SEXP alpha, SEXP beta, SEXP lambda, SEXP lg){
const int nx = LENGTH(x);
const int na = LENGTH(alpha);
const int nb = LENGTH(beta);
const int nl = LENGTH(lambda);
SEXP ret;
PROTECT(ret = allocVector(REALSXP, nx));
ddelap_f(REAL(x), nx, REAL(alpha), na, REAL(beta), nb,
REAL(lambda), nl, INTEGER(lg), REAL(ret));
UNPROTECT(1);
return(ret);
}
Also, I don't use the "automatic" concatenation of the "c_" to my
Fortran functions, but name them individually and use Fortran 2003 ISO
C bindings (except for booleans).
If it helps, take a look at the source code at
<https://bitbucket.org/aadler/delaporte>. As of now, it passes all R
checks and so must have appeased the registration requirements 8-)
Thank you,
Avi
More information about the R-package-devel
mailing list