Rinternals.h and undefined symbols
Note though that you should include C header files inside extern "C" in
your C++ code. 'Writing R Extensions' says
Some @R{} header files are C and not C++ header files and should be
included within an @code{extern "C"} block: for clarity this is
advisable for all @R{} header files.
On Mon, 19 Mar 2007, Duncan Murdoch wrote:
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
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595