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.c
If 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