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_CallMethodDefS3_S6 _ $ nm bgx.Rcheck/bgx/libs/bgx.so | grep R_registerRoutines U _Z18R_registerRoutinesP8_DllInfoPK12R_CMethodDefPK15R_CallMethodDefS3_S6 _ Why does it have this funny name? If I look at libR.so, I get an ordinary symbol name: $ nm ~/lib64/R/lib/libR.so | grep R_registerRoutines 0000000000032f80 T R_registerRoutines I get normal symbol names for R functions not in Rinternals.h and there is no problem there. For example: nm bgx.Rcheck/bgx/libs/bgx.so | grep Rprintf U Rprintf $ nm ~/lib64/R/lib/libR.so | grep Rprintf 0000000000129690 T Rprintf The shared library dependencies are also fine: $ ldd bgx.Rcheck/bgx/libs/bgx.so libR.so => /home/et04/lib64/R/lib/libR.so (0x0000002a95676000) libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000002a95a80000) libm.so.6 => /lib64/tls/libm.so.6 (0x0000002a95c70000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000002a95df7000) libc.so.6 => /lib64/tls/libc.so.6 (0x0000002a95f02000) libRblas.so => /home/et04/lib64/R/lib/libRblas.so (0x0000002a96136000) libg2c.so.0 => /usr/lib64/libg2c.so.0 (0x0000002a96262000) libreadline.so.4 => /usr/lib64/libreadline.so.4 (0x0000002a96383000) libncurses.so.5 => /usr/lib64/libncurses.so.5 (0x0000002a964bc000) libdl.so.2 => /lib64/libdl.so.2 (0x0000002a96618000) /lib64/ld-linux-x86-64.so.2 (0x000000552aaaa000) My LD_LIBRARY_PATH environmental variable is set appropriately. Any ideas? Thanks, E
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_CallMethodDefS3_S6 > _ > > $ nm bgx.Rcheck/bgx/libs/bgx.so | grep R_registerRoutines > U > _Z18R_registerRoutinesP8_DllInfoPK12R_CMethodDefPK15R_CallMethodDefS3_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" { } ? Duncan Murdoch> > $ nm ~/lib64/R/lib/libR.so | grep R_registerRoutines > 0000000000032f80 T R_registerRoutines > > I get normal symbol names for R functions not in Rinternals.h and > there is no problem there. For example: > > nm bgx.Rcheck/bgx/libs/bgx.so | grep Rprintf > U Rprintf > > $ nm ~/lib64/R/lib/libR.so | grep Rprintf > 0000000000129690 T Rprintf > > The shared library dependencies are also fine: > > $ ldd bgx.Rcheck/bgx/libs/bgx.so > libR.so => /home/et04/lib64/R/lib/libR.so (0x0000002a95676000) > libstdc++.so.6 => /usr/lib64/libstdc++.so.6 > (0x0000002a95a80000) > libm.so.6 => /lib64/tls/libm.so.6 (0x0000002a95c70000) > libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000002a95df7000) > libc.so.6 => /lib64/tls/libc.so.6 (0x0000002a95f02000) > libRblas.so => /home/et04/lib64/R/lib/libRblas.so > (0x0000002a96136000) > libg2c.so.0 => /usr/lib64/libg2c.so.0 (0x0000002a96262000) > libreadline.so.4 => /usr/lib64/libreadline.so.4 > (0x0000002a96383000) > libncurses.so.5 => /usr/lib64/libncurses.so.5 > (0x0000002a964bc000) > libdl.so.2 => /lib64/libdl.so.2 (0x0000002a96618000) > /lib64/ld-linux-x86-64.so.2 (0x000000552aaaa000) > > My LD_LIBRARY_PATH environmental variable is set appropriately. > > Any ideas? > > Thanks, > > E > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel
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_CallMethodDef >>>> S3 _S6 _ >>>> $ nm bgx.Rcheck/bgx/libs/bgx.so | grep R_registerRoutines >>>> U >>>> _Z18R_registerRoutinesP8_DllInfoPK12R_CMethodDefPK15R_CallMethodDef >>>> 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?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... ): Ernest> > Duncan Murdoch > > >> The two routines that I am registering are also wrapped in extern >> "C". >> Ernest >>> Duncan Murdoch >>> >>> >>>> $ nm ~/lib64/R/lib/libR.so | grep R_registerRoutines >>>> 0000000000032f80 T R_registerRoutines >>>> I get normal symbol names for R functions not in Rinternals.h >>>> and there is no problem there. For example: >>>> nm bgx.Rcheck/bgx/libs/bgx.so | grep Rprintf >>>> U Rprintf >>>> $ nm ~/lib64/R/lib/libR.so | grep Rprintf >>>> 0000000000129690 T Rprintf >>>> The shared library dependencies are also fine: >>>> $ ldd bgx.Rcheck/bgx/libs/bgx.so >>>> libR.so => /home/et04/lib64/R/lib/libR.so >>>> (0x0000002a95676000) >>>> libstdc++.so.6 => /usr/lib64/libstdc++.so.6 >>>> (0x0000002a95a80000) >>>> libm.so.6 => /lib64/tls/libm.so.6 (0x0000002a95c70000) >>>> libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000002a95df7000) >>>> libc.so.6 => /lib64/tls/libc.so.6 (0x0000002a95f02000) >>>> libRblas.so => /home/et04/lib64/R/lib/libRblas.so >>>> (0x0000002a96136000) >>>> libg2c.so.0 => /usr/lib64/libg2c.so.0 (0x0000002a96262000) >>>> libreadline.so.4 => /usr/lib64/libreadline.so.4 >>>> (0x0000002a96383000) >>>> libncurses.so.5 => /usr/lib64/libncurses.so.5 >>>> (0x0000002a964bc000) >>>> libdl.so.2 => /lib64/libdl.so.2 (0x0000002a96618000) >>>> /lib64/ld-linux-x86-64.so.2 (0x000000552aaaa000) >>>> My LD_LIBRARY_PATH environmental variable is set appropriately. >>>> Any ideas? >>>> Thanks, >>>> E >>>> ______________________________________________ >>>> R-devel at r-project.org mailing list >>>> https://stat.ethz.ch/mailman/listinfo/r-devel >
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