[R] C interface

Matt Shotwell shotwelm at musc.edu
Fri Jun 18 17:54:37 CEST 2010


Michael, 

Your function 'test' doesn't utilize any C++ features. Is there another
reason you are using a C++ compiler (g++)? If not, why not just use a C
compiler? You can then get rid of the 'extern C{}' wrapper, the
'__cdecl' declaration, and the MAKEFLAGS variable. Also, you may know
that the '__cdecl' modifier doesn't affect the R calling convention
(i.e. .C, .Call, etc.), but rather how arguments are cleaned up on the C
stack. I suppose since Rprintf uses a variable argument list, it's
proper to use the __cdecl calling convention. However, I believe gcc
uses this convention by default, and this low-level business shouldn't
be of much concern to R extension developers (I think, and hope). The
developers of the Rcpp package would be in a better position to comment
on this.

The inline package does essentially what you did, but with a little less
work, and none of the funny business. The following worked for me (on
Debian Linux): 

> library(inline)
> 
> code <- "
+   SEXP result;
+   PROTECT(result = NEW_NUMERIC(1));
+   double* ptr=NUMERIC_POINTER(result);
+   double t = *REAL(s);
+   double u = t-floor(t)-0.5;
+   if(u>0) *ptr=-1+4*u; else *ptr=-1-4*u;
+   Rprintf(\"The value is %f\", *ptr);
+   UNPROTECT(1);
+   return result;
+ "
> 
> test   <- cfunction(signature(s="character"), code, 
+               convention=".Call", language="C")
> 
> testpp <- cfunction(signature(s="character"), code,
+               convention=".Call", language="C++")
> 
> test(1)
The value is 1.000000[1] 1
> testpp(1)
The value is 1.000000[1] 1

Take a look at the code in the 'code' slot of test and testpp also.

-Matt

On Fri, 2010-06-18 at 10:18 -0400, michael meyer wrote:
> Greetings,
> 
> I am trying to call simple C-code from R.
> I am on Windows XP with RTools installed.
> 
> The C-function is
> 
> #include <R.h>
> #include <Rinternals.h>
> #include <Rmath.h>
> #include <Rdefines.h>
> 
> // prevent name mangling
> extern "C" {
> 
> SEXP __cdecl test(SEXP s){
> 
>   SEXP result;
>   PROTECT(result = NEW_NUMERIC(1));
>   double* ptr=NUMERIC_POINTER(result);
>   double t = *REAL(s);
>   double u = t-floor(t)-0.5;
>   if(u>0) *ptr=-1+4*u; else *ptr=-1-4*u;
>   Rprintf("The value is %f", *ptr);
>   UNPROTECT(1);
>   return result;
> }
> 
> };
> 
> It is compiled with
> 
> R CMD SHLIB source.c
> 
> with flag
> 
> MAKEFLAGS="CC=g++"
> 
> If I compile with the default flags I get an error message about an
> undefined reference to "__gxx_personality_v0".
> However when I call this code from R with
> 
> test <- function(t){
>   .Call("test",t)
> }
> dyn.load("./source.dll")
> test(0)
> dyn.unload("./source.dll")
> 
> then R crashes.
> I have a vague idea of the issue of calling conventions and was hoping that
> the __cdecl
> specifier would force the appropriate convention.
> I also have Cygwin installed as part of the Python(x,y) distribution but I
> am assuming that
> R CMD SHLIB source.c
> calls the right compiler.
> 
> What could the problem be?
> 
> Many thanks,
> 
> Michael
> 
> 	[[alternative HTML version deleted]]
> 
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
-- 
Matthew S. Shotwell
Graduate Student
Division of Biostatistics and Epidemiology
Medical University of South Carolina
http://biostatmatt.com



More information about the R-help mailing list