[Rd] Rinternals.h and undefined symbols

Ernest Turro ernest.turro at ic.ac.uk
Tue Mar 20 01:55:06 CET 2007


On 20 Mar 2007, at 00:50, Duncan Murdoch wrote:

> On 3/19/2007 8:41 PM, Ernest Turro wrote:
>> On 20 Mar 2007, at 00:18, Duncan Murdoch wrote:
>>> On 3/19/2007 7:41 PM, Ernest Turro wrote:
>>>> On 19 Mar 2007, at 21:32, Duncan Murdoch wrote:
>>>>> On 3/19/2007 5:23 PM, Ernest Turro wrote:
>>>>>> Hi,
>>>>>> I'm trying to register my native routines using   
>>>>>> R_registerRoutines  (...). I can compile the code, but the   
>>>>>> loader cannot resolve the  symbol:
>>>>>> undefined symbol:     
>>>>>> _Z18R_registerRoutinesP8_DllInfoPK12R_CMethodDefPK15R_CallMethodD 
>>>>>> ef S3 _S6 _
>>>>>> $ nm bgx.Rcheck/bgx/libs/bgx.so | grep R_registerRoutines
>>>>>>                   U     
>>>>>> _Z18R_registerRoutinesP8_DllInfoPK12R_CMethodDefPK15R_CallMethodD 
>>>>>> ef S3 _S6 _
>>>>>> Why does it have this funny name? If I look at libR.so, I get   
>>>>>> an   ordinary symbol name:
>>>>> That looks like C++ name mangling.  Are you wrapping your    
>>>>> declarations in
>>>>>
>>>>> extern "C" { }
>>>>>
>>>>> ?
>>>> Yeah, the routine is literally just:
>>>> extern "C"
>>>>    void R_init_bgx(DllInfo *info) {
>>>>      R_registerRoutines(info, cMethods,NULL,NULL,NULL);
>>>>    }
>>>> with cMethods declared outside as a static const R_CMethodDef.
>>> I'm no C++ expert, but that looks like it declares R_init_bgx to  
>>> be  a "C" routine, but not R_registerRoutines (which is what the  
>>> error  was about).  Its declaration is in Rdynload.h:
>>>
>>> #ifdef __cplusplus
>>> extern "C" {
>>> #endif
>>> int R_registerRoutines(DllInfo *info, const R_CMethodDef * const   
>>> croutines,
>>> 		       const R_CallMethodDef * const callRoutines,
>>> 		       const R_FortranMethodDef * const fortranRoutines,
>>>                        const R_ExternalMethodDef * const   
>>> externalRoutines);
>>>
>>> Rboolean R_useDynamicSymbols(DllInfo *info, Rboolean value);
>>> #ifdef __cplusplus
>>> }
>>> #endif
>>>
>>> so maybe your compiler doesn't define __cplusplus, or you didn't   
>>> include R_ext/Rdynload.h?


Duncan, you hit the nail on the head. Thanks so much.

If you download R-2.4.1.tar.gz from CRAN you will find that the  
extern "C" is missing in Rdynload.h! I added it to my copy and my  
code compiles now. I wonder why it's missing. Has this been fixed in  
cvs?

Thanks,

Ernest

PS. you don't need the braces after extern "C"



>> Thanks for the reply.
>> __cplusplus is defined and I do #include <R_ext/Rdynload.h>  
>> (after  all, it does compile)...
>> I've tried this on two different machines, so it's not a problem   
>> specific to my setup either...  ):
>
> Here I'm just guessing:  you don't wrap the whole function in  
> extern "C", you just put extern "C" ahead of its header. That's not  
> the usual way it's done, but I don't know C++ well enough to know  
> if it matters. Nevertheless, I'd try
>
>  extern "C" {
>     void R_init_bgx(DllInfo *info) {
>       R_registerRoutines(info, cMethods,NULL,NULL,NULL);
>     }
>  }
>
> just to see if it helps.
>
> Duncan Murdoch



More information about the R-devel mailing list