[Rd] Rinternals.h and undefined symbols
Duncan Murdoch
murdoch at stats.uwo.ca
Tue Mar 20 02:00:12 CET 2007
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
More information about the R-devel
mailing list