[Rd] read.table() code fails outside of the utils package
Andrew Piskorski
atp at piskorski.com
Mon Apr 21 22:13:16 CEST 2014
On Mon, Apr 21, 2014 at 06:44:05PM +0100, Prof Brian Ripley wrote:
> On 21/04/2014 18:08, Andrew Piskorski wrote:
> >> .External(utils:::C_readtablehead, ...)
> >
> > Ah, that works fine, and is nice and simple. So problem solved, thank
> > you!
> >
> > I do still wonder though, with the C symbol made visible in utils.so,
>
> That isn't true on platforms which support hiding entry points. Try
>
> % nm -g library/utils/libs/utils.so | grep readtablehead
>
> on Linux.
What isn't true? That .External(utils:::C_readtablehead, ...)
should work for me under stock R 3.0.1? My Linux (Ubuntu 12.04.3 LTS)
definitely does seem to support hiding entry points.
I have two separate installs, both built from source. The first one
is stock, and the lower-case "t" here indicates that the readtablehead
symbol is local:
andy at odo:~$ nm /usr/local/pkg/R-3.1-branch-20140416/lib/R/library/utils/libs/x86_64/utils.so | grep readtablehead
00000000000059a0 t readtablehead
This second install is where I added "attribute_visible" to
readtablehead and recompiled, the upper-case "T" means it is a global
symbol:
andy at odo:~$ nm /usr/local/pkg/R-3.1-branch-20140418/lib/R/library/utils/libs/x86_64/utils.so | grep readtablehead
00000000000059c0 T readtablehead
Fortunately, calling .External(utils:::C_readtablehead, ...) works
with either of those installs. But writing my won C code that calls
readtablehead only works in the second one where the symbol is global.
> > how come this still failed?:
> >
> > .External("readtablehead", ..., PACKAGE="utils")
> > Error: "readtablehead" not available for .External() for package "utils"
>
> Rather, you need to tell us why that should have worked ....
That exact style of call DOES work for every cross-package use of .C
and .Call I've tried in my own code. But I have never "registered"
any of my C code with R. Obviously there is something different about
readtablehead and/or the utils package (probably the latter), and I am
trying to understand what it is.
> Maybe you failed to read in the code
>
> R_init_utils(DllInfo *dll)
> {
> R_registerRoutines(dll, NULL, CallEntries, NULL, ExtEntries);
> R_useDynamicSymbols(dll, FALSE);
> R_forceSymbols(dll, TRUE);
> }
I believe you are implying that using R_registerRoutines in a package
changes the behavior of .Call() and .External() such that ONLY
registered functions will be found, even if I invoke .External() with
a string function name like "readtablehead" rather than the registered
value C_readtablehead. While if I do not register any C functions at
all in a package, then using a string name like "readtablehead" will
work as long as that C function symbol is visible.
> > .External("readtablehead", ..., PACKAGE="utils")
> > Error: "readtablehead" not available for .External() for package "utils"
> See 'Writing R Extensions'.
I already had, many times. If this question is answered there, it was
not apparent to me.
--
Andrew Piskorski <atp at piskorski.com>
More information about the R-devel
mailing list