[R-pkg-devel] R_registerRoutines, etc.

Dirk Eddelbuettel edd at debian.org
Sat Apr 22 23:44:52 CEST 2017


On 23 April 2017 at 09:25, Rolf Turner wrote:
| I have, like many others it would appear, been struggling with
| the new-ish convention of requiring --- or quasi-requiring --- that 
| "routines" be "registered" and the warning generated by R CMD check to 
| the effect:
| 
| > Found no calls to: 'R_registerRoutines', 'R_useDynamicSymbols'
| >
| > It is good practice to register native routines and to disable symbol
| > search.
| >
| > See 'Writing portable packages' in the 'Writing R Extensions' manual.
| 
| Well, the material in the "Writing R Extensions" manual is completely 
| incomprehensible to the human mind, which is what I'm equipped with. 
| However I found a posting by Ege Rubak on this topic which sent me by a 
| slightly roundabout route to a posting by Dirk Eddelbuttel

There is a transcribed Umlaut in there:  Eddelbuettel (ie 'ue' not 'u')

| which told me to use package_native_routine_registration_skeleton() from 
| the tools package.
| 
| After a bit more struggle, I found that that did the trick.  I have, 
| however, a couple of questions remaining.
| 
| (1) I found that having an R function with the same name as that of a
| routine (Fortran subroutine in this case) that it called, causes all 
| sorts of chaos.  I had a function "binsrt" that called a Fortran 
| subroutine named "binsrt" and a function "mnnd" that called a Fortran 
| subroutine named "mnnd".  This induced several fairly mysterious 
| warnings.  I resolved the issue by renaming the R functions "binsrtR"
| and "mnndR" respectively, so as to eliminate the name conflict.
| 
| Would this be the recommended procedure, or is there a cleverer way to 
| eliminate the problem?

That has hit me too, and I also found the error message less than perfectly
clear.  It all makes sense in the large sense -- we now register functions,
and R and compiled code (C++ for me, Fortran for you) "compete" for unique
identifiers.

The "official" way in Writing R Extensions fixes this by automagically
prefixing functions called via .Call() with a "c_" prefix.  You can turn that
on in the NAMESPACE file as further argument to useDynLib().  I am not (yet?)
doing this in all packages, and I "spied" on one recent update of a package
by an R Core member that didn;t either.  When in Rome ...
 
| (2) The help for package_native_routine_registration_skeleton() says:
| 
| > Optionally the skeleton will include declarations for the registered
| > routines: they should be checked against the C/Fortran source code, not
| > least as the number of arguments is taken from the R code. For .Call and
| > .External calls they will often suffice, but for .C and .Fortran calls
| > the void * arguments would ideally be replaced by the actual types.
| 
| OTOH a post from Ege Rubak (answering a question like unto mine from 
| another user) basically says "Don't bother.  It doesn't really matter."
| 
| However, being a Good Little Boy, I like to follow instructions exactly. 
|   So I tried to replace the "void *" strings by the "actual types", but 
| then all hell broke loose.  Consequently I went back to the "void *" 
| structures.  That appears to work, but:
| 
|     (a) Are there any perils lurking if one just leaves "void *" as is,
|         throughout?
| 
|     (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 ;-)

Dirk

-- 
http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org



More information about the R-package-devel mailing list