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]]
Hello, This is not the appropriate mailing list. Use R-devel for questions about C, etc ... One thing that might help you is the inline package. require( inline ) fx <- cfunction( signature( s = "numeric" ), ' 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; ', verbose = TRUE ) fx( 10 ) The verbose = TRUE argument will show you how inline runs the show. Romain Le 18/06/10 16:18, michael meyer a ?crit :> > 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.cIf you want C++, then name your file source.cpp SHLIB compiles files with .c extensions with a C compiler, which will not be happy about extern "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-- Romain Francois Professional R Enthusiast +33(0) 6 28 91 30 30 http://romainfrancois.blog.free.fr |- http://bit.ly/98Uf7u : Rcpp 0.8.1 |- http://bit.ly/c6YnCi : graph gallery collage `- http://bit.ly/bZ7ltC : inline 0.3.5
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