[R-pkg-devel] R_registerRoutines, etc.

Duncan Murdoch murdoch.duncan at gmail.com
Sun Apr 23 13:05:28 CEST 2017


On 23/04/2017 6:38 AM, Rolf Turner wrote:
> On 23/04/17 21:57, Duncan Murdoch wrote:
>> On 22/04/2017 5:25 PM, Rolf Turner wrote:
>
> <SNIP>
>>>
>>> (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?
>>
>> I think renaming the Fortran would make more sense:  the R routine may
>> be used by your package users, whereas the Fortran routine may only be
>> used by the R routine.  But there are probably lots of exceptions to this.
>
> Hmmm.  Don't follow this.  Sorry to be slow.  It just seemed easier to
> me to fiddle with the R code than with the Fortran code.  I think I
> could go either way.

In one common case, the Fortran routine is written specifically as an 
interface to R, and is only called by the R routine that was written as 
that end of the interface.  That's what I was talking about.  But there 
are also situations where you have a Fortran subroutine that is used for 
many purposes besides the call from R; then renaming it would be more 
trouble.

>
>>> (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?
>>
>> Not immediately, but a couple of potential ones:
>>
>>  - If you change the type of something in the future, "void *" won't
>> care, but the compiler might catch a the change if you were more explicit.
>>
>>  - R CMD check generally becomes stricter over time, so it's possible it
>> will complain about "void *" in the future.
>
> Yeah, it was something like the latter that nagged the back of my mind.
> So I really would like to change the "void *" constructions.
> Hence the following may be very helpful.
>
>>>     (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?
>>
>> Looks like
>>
>> extern void F77_NAME(mnnd)(double *, double *, int *, double *, double *);
>>
>> to me.
>
> Looks quite plausible.  I'll give it a try and report back.  (Later; not
> tonight, Josephine.  Past my bedtime. :-) )  My recollection is that I
> tried something like that, but said "integer" rather than "int".
> Which is, I guess, Fortran-ese rather than C-ese.  And I guess the
> latter is called for.  In retrospect, I was being silly, since I said
> "double" (C-ese) rather than "double precision" (Fortran-ese).  So
> saying "int" would have been consistent.  Psigh!

Good luck!

Duncan Murdoch



More information about the R-package-devel mailing list