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 OrthoFunctions.c with flag MAKEFLAGS="CC=g++" However when I call this code from R with test <- function(t){ .Call("test",t) } dyn.load("./OrthoFunctions.dll") test(0) dyn.unload("./OrthoFunctions.dll") then R crashes. If I compile with the default flags (no extern "C", no __cdecl) I get an error message about an undefined reference to "__gxx_personality_v0": C:\...>R CMD SHLIB OrthoFunctions.c C:/Programme/R/R-2.10.1/etc/Makeconf:151: warning: overriding commands for target `.c.o' C:/Programme/R/R-2.10.1/etc/Makeconf:142: warning: ignoring old commands for target `.c.o' C:/Programme/R/R-2.10.1/etc/Makeconf:159: warning: overriding commands for target `.c.d' C:/Programme/R/R-2.10.1/etc/Makeconf:144: warning: ignoring old commands for target `.c.d' C:/Programme/R/R-2.10.1/etc/Makeconf:169: warning: overriding commands for target `.m.o' C:/Programme/R/R-2.10.1/etc/Makeconf:162: warning: ignoring old commands for target `.m.o' g++ -I"C:/Programme/R/R-2.10.1/include" -O2 -Wall -c OrthoFunctions.c -o OrthoFunctions.o gcc -shared -s -o OrthoFunctions.dll tmp.def OrthoFunctions.o -LC:/Programme/R/R-2.10.1/bin -lR OrthoFunctions.o:OrthoFunctions.c:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0' collect2: ld returned 1 exit status 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]]
On Jun 18, 2010, at 10:23 AM, michael meyer <mjhmeyer at googlemail.com> 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 OrthoFunctions.c > > with flag > > MAKEFLAGS="CC=g++" >That is entirely wrong - g++ is not a C compiler. Cheers, Simon> > However when I call this code from R with > > test <- function(t){ > .Call("test",t) > } > dyn.load("./OrthoFunctions.dll") > test(0) > dyn.unload("./OrthoFunctions.dll") > > then R crashes. > > If I compile with the default flags (no extern "C", no __cdecl) I get an > error message about an undefined reference to "__gxx_personality_v0": > > C:\...>R CMD SHLIB OrthoFunctions.c > C:/Programme/R/R-2.10.1/etc/Makeconf:151: warning: overriding commands for > target `.c.o' > C:/Programme/R/R-2.10.1/etc/Makeconf:142: warning: ignoring old commands for > target `.c.o' > C:/Programme/R/R-2.10.1/etc/Makeconf:159: warning: overriding commands for > target `.c.d' > C:/Programme/R/R-2.10.1/etc/Makeconf:144: warning: ignoring old commands for > target `.c.d' > C:/Programme/R/R-2.10.1/etc/Makeconf:169: warning: overriding commands for > target `.m.o' > C:/Programme/R/R-2.10.1/etc/Makeconf:162: warning: ignoring old commands for > target `.m.o' > g++ -I"C:/Programme/R/R-2.10.1/include" -O2 -Wall -c > OrthoFunctions.c -o OrthoFunctions.o > gcc -shared -s -o OrthoFunctions.dll tmp.def OrthoFunctions.o > -LC:/Programme/R/R-2.10.1/bin -lR > OrthoFunctions.o:OrthoFunctions.c:(.eh_frame+0x11): undefined reference to > `__gxx_personality_v0' > collect2: ld returned 1 exit status > > > > 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-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > >
Michael, You are getting confused in compiler minutia when you could be concentrating on your code. The inline package can help here. Consider the snippet below which loads inline, defines your function body sans headers etc and then uses the magic of inline to compile, link and load your function: ----------------------------------------------- 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\\n", *ptr); UNPROTECT(1); return result; ' fun <- cfunction(signature(s="numeric"), code) fun(0.0001) ----------------------------------------------- Pasted in my R session I get:> 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\\n", *ptr); + UNPROTECT(1); + return result; + '> > fun <- cfunction(signature(s="numeric"), code) > > fun(0.0001)The value is 0.999600 [1] 0.9996>(I added a newline which, given that the code is character string, needed to be escaped.) If you like inline, you may like it even more in conjunction with Rcpp as the program becomes shorter and simpler thanks to as<>() and wrap():> code <- '+ double t = as<double>(s); + double u = t-floor(t)-0.5; + if (u>0) t=-1+4*u; else t=-1-4*u; + std::cout << "The value is " << t << std::endl; + return wrap(t); + '> fun <- cxxfunction(signature(s="numeric"), code, plugin="Rcpp") > > fun(0.0001)The value is 0.9996 [1] 0.9996>Rcpp has a few vignettes that help getting started. The rcpp-devel list can help with questions. -- Regards, Dirk
I'm not a windows expert. You have C code file (not cc or cpp):> R CMD SHLIB OrthoFunctions.cand you use g++ compiler... ok, we can use c++ compiler for c.. but it's looks like c++ code with c code inside:> extern "C" {Try it without "extern "C" and with gcc compiler instead g++. regards, daniel 2010/6/18 michael meyer <mjhmeyer at googlemail.com>:> 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 OrthoFunctions.c > > with flag > > MAKEFLAGS="CC=g++" > > > However when I call this code from R with > > test <- function(t){ > ?.Call("test",t) > } > dyn.load("./OrthoFunctions.dll") > test(0) > dyn.unload("./OrthoFunctions.dll") > > then R crashes. > > If I compile with the default flags (no extern "C", no __cdecl) I get an > error message about an undefined reference to "__gxx_personality_v0": > > C:\...>R CMD SHLIB OrthoFunctions.c > C:/Programme/R/R-2.10.1/etc/Makeconf:151: warning: overriding commands for > target `.c.o' > C:/Programme/R/R-2.10.1/etc/Makeconf:142: warning: ignoring old commands for > target `.c.o' > C:/Programme/R/R-2.10.1/etc/Makeconf:159: warning: overriding commands for > target `.c.d' > C:/Programme/R/R-2.10.1/etc/Makeconf:144: warning: ignoring old commands for > target `.c.d' > C:/Programme/R/R-2.10.1/etc/Makeconf:169: warning: overriding commands for > target `.m.o' > C:/Programme/R/R-2.10.1/etc/Makeconf:162: warning: ignoring old commands for > target `.m.o' > g++ -I"C:/Programme/R/R-2.10.1/include" ? ? ? ?-O2 -Wall ?-c > OrthoFunctions.c -o OrthoFunctions.o > gcc -shared -s -o OrthoFunctions.dll tmp.def OrthoFunctions.o > -LC:/Programme/R/R-2.10.1/bin -lR > OrthoFunctions.o:OrthoFunctions.c:(.eh_frame+0x11): undefined reference to > `__gxx_personality_v0' > collect2: ld returned 1 exit status > > > > 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-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >