Matt,
On Dec 30, 2007, at 5:25 PM, Matt Calder wrote:
I am still having trouble dyn.load'ing some code into R. I have
isolated the problem, I wonder if someone could explain what I am
seeing.
I think the problem is that a symbol defined in my compiled code
clashes with one already defined in R.
The result of redefining a symbol is very much system-dependent. For
example on Mac OS X it has no adverse effects (i.e your symbols are
always private unless linked against), because it uses a two-level
namespace, but on Linux (and most other unices) it does as the
namespace of an executable is shared among all modules (dynamic and
static).
The result is that the function in my code is not called. Here is an
example
// lnktst.cc
extern "C"
{
void func(double *out1, double *out2);
void dnrm2_(double *out);
void dnrm3_(double *out);
}
void func(double *out1, double *out2)
{
dnrm2_(out1);
dnrm3_(out2);
}
void dnrm2_(double *out)
{
*out = 1234.5;
}
void dnrm3_(double *out)
{
*out = 6789.0;
}
// End of lnktst.cc
When I compile:
g++ -shared -static -o lnktst.so lnktst.cc
and then in R I call "func"
dyn.load("lnktst.so")
.C('func', double(1), double(1))
[[1]]
[1] 0
[[2]]
[1] 6789
So, as you can see, the function "dnrm2_" is not called whereas
"dnrm3_" is, even though both functions are identical in form. Now,
I believe dnrm2_ is a BLAS function, and so it is likely R already
has a copy floating around.
Yes, indeed (it's a BLAS level 1 Fortran function, and usually to be
found in libRblas.so or the external BLAS implementation).
However, it surprises me that the "-static" option does
not force the call in my code to "dnrm2_" to be linked to the function
defined in my code.
You are confusing the purpose of -static: it only ensures that static
libraries are used at link time where possible, it doesn't affect your
code in any way. What you really want is to use
static void dnrm2_(double *out);
in your code instead.
In general, it is a bad idea to use external symbols that clash with
other libraries (in particular widespread ones such as BLAS),
especially if your function doesn't perform the same operation. It is
a good idea to declare all functions that you use internally (i.e.
that should not be visible to R) as static. However, all this is true
for C programming in general, not just in conjunction with R.
Cheers,
Simon
I have been writing C code for Splus for quite a while and don't
recall
ever running across this issue. However, I am new to R, so I wonder,
am
I missing something obvious?
I am running this on Ubuntu Linux, the output of uname -a is:
Linux calder-linux 2.6.22-14-generic #1 SMP Sun Oct 14 23:05:12 GMT
2007 i686 GNU/Linux
Thanks for any help,
Matt