On Nov 12, 2008, at 23:16 , Jeff Ryan wrote:
Charles,
I've looked through the "Writing R Extensions" manual, and can't find
this documented very clearly. A previous question to the list gave
me
the very kind response pasted below. I've looked at the suggested
examples (lme4 using C functions from Matrix).
It isn't really "clearly" explained. I will give it a try though.
You can't use compiled/packaged functions from within _your_ compiled
code unless the package that you are referring to (affxparser) makes
them available for export.
If affxparser doesn't do this you are back to Dirk's method.
For the sake of others who have gone down this road I will explain
what I know, and probably in the process learn what I may be doing
wrong. (all of this I learned by reading the sources for R and lme4
and Matrix).
Matrix has a copy of the Matrix.h header in its /inst directory,
specifically /inst/include/Matrix.h
This gets installed as /include/Matrix.h, which is where LinkingTo
links to during compilation.
You (or the affxparser author) will also need a handful of C calls
that are complementary to ones in the package you are getting the
functions from.
An example from Matrix:
/include/Matrix_stubs.c contains
...
CHM_DN attribute_hidden
M_as_cholmod_dense(CHM_DN ans, SEXP x)
{
static CHM_DN(*fun)(CHM_DN,SEXP) = NULL;
if(fun == NULL)
fun = (CHM_DN(*)(CHM_DN,SEXP))
R_GetCCallable("Matrix", "as_cholmod_dense");
return fun(ans, x);
}
...
FWIW this is not exactly the most efficient way to do it. It's much
easier to do it the commonly used way of setting the function pointers
directly (taking the situation above):
CHM_DN(*M_as_cholmod_dense)(CHM_DN,SEXP);
in the initialization function of the package populate all the pointers:
M_as_cholmod_dense = (CHM_DN(*)(CHM_DN,SEXP)) R_GetCCallable("Matrix",
"as_cholmod_dense");
By setting the functions right away you save yourself the trouble of
checking it on every call and using a function call twice. This allows
you to use the function transparently in your code, so you don' t need
any function wrappers:
x = M_as_cholmod_dense(a, b);
This is pretty much standard C programming, so the above should be
quite obvious (I hope).
The only reason to do it the complicated way above is if you want to
do some extra processing in the wrapper function so your function
pointer is not visible from outside the function.
Cheers,
Simon
The above is far from obvious, so I will try my best to explain.
With respect to the R_GetCCallable call, Writing R Extensions says:
" p_myCfun = R_GetCCallable("packA", "myCfun");
The author of packB is responsible for ensuring that p_myCfun has an
appropriate declaration. What exactly that means was hard to determine
at first."
Taking the first line, the first CHM_DN is the function return type
(could be int, SEXP, etc), and the second (along with the SEXP) is the
argument type(s).
Generalized you'd have something like:
SEXP attribute_hidden
FUNNAME(SEXP ans, SEXP x)
{
static SEXP(*fun)(SEXP,SEXP) = NULL;
if(fun == NULL)
fun = (SEXP(*)(SEXP,SEXP))
R_GetCCallable("PACKAGE", "FUNCTION");
return fun(ans, x);
}
lme4 then simply "#include"s this .c file in a file
/src/local_stubs.c, which is compiled right along side of the src code
in lme4.
At this point you can then use the functions that are
'exported/registered' as you would a C function defined in your own
package.
The other side of this is what the Matrix (affxparser?) package needs
to do. It needs a registration routine that specifically registers
the routines as callable using:
R_RegisterCCallable (which is documented in Writing R Extensions)
In Matrix this is in /src/init.c via a macro.
A simpler in-progress bit of code can be found in the /dev branch of
xts on R-forge. Take a look at
http://r-forge.r-project.org/scm/?group_id=118
/dev/src/init.c
/dev/inst/include/xts.h
/dev/inst/include/xts_stubs.c
As far as C++ goes, I would suspect the Matrix package again has all
the bits you are looking for.
HTH
Jeff
--
Jeffrey Ryan
[EMAIL PROTECTED]
ia: insight algorithmics
www.insightalgo.com
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel