From murdoch at stats.uwo.ca  Tue Mar 20 02:00:12 2007
From: murdoch at stats.uwo.ca (Duncan Murdoch)
Date: Mon, 19 Mar 2007 21:00:12 -0400
Subject: [Rd] Rinternals.h and undefined symbols
In-Reply-To: <BE02BC30-532E-4398-AF56-BA5B76DDD308@ic.ac.uk>
References: <9001E5A6-9080-4224-92ED-4867C858C637@ic.ac.uk>
	<45FF016B.3060505@stats.uwo.ca>
	<4E0FCC76-D2E2-40E3-A2F7-C15519D286C1@ic.ac.uk>
	<45FF2866.7060705@stats.uwo.ca>
	<B97996F0-05E3-424E-B79F-BA9C9EE125FE@ic.ac.uk>
	<45FF2FD4.1080601@stats.uwo.ca>
	<BE02BC30-532E-4398-AF56-BA5B76DDD308@ic.ac.uk>
Message-ID: <45FF321C.2020400@stats.uwo.ca>

On 3/19/2007 8:55 PM, Ernest Turro wrote:
> 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?

Yes, it's a new addition Duncan Temple Lang added in November.  I didn't 
remember that or I would have mentioned it.

Duncan Murdoch

> 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



[Rd] Rinternals.h and undefined symbols
Duncan Murdoch