[R] Calling R from C
Prof Brian Ripley
ripley at stats.ox.ac.uk
Tue May 9 13:18:37 CEST 2006
I agree with Roger you should not leave this to chance. But in this case
it is cleaner to do the coercions in the C code, e.g. (untested)
SEXP doloop(SEXP nt)
{
int x = asInteger(nt);
if(x == NA_INTEGER) error("'nt' must be coercible to an integer")
Rprintf("x: %d\n", x);
...
}
since your code does no check on the length of nt as well as none on its
type nor its value.
On Tue, 9 May 2006, Roger Bivand wrote:
> On Tue, 9 May 2006, Ingmar Visser wrote:
>
>> Dear R-helpers,
>>
>> I'm trying to transfer a loop from R code to C to improve performance using
>> the .Call interface. However, I ran into problems before even getting
>> started, and I hope (fear) I'm missing something completely obvious here.
>>
>> I use the following C function (passing an integer to the C function and
>> printing it):
>>
>> #include <R.h>
>> #include <Rinternals.h>
>>
>> SEXP doloop(SEXP nt) {
>> int x=INTEGER(nt)[0];
>> Rprintf("x: %d \n", x);
>> SEXP ans;
>> PROTECT(ans=allocVector(REALSXP,1));
>> REAL(ans)[0]=0;
>> Rprintf("init ans: %f \n",REAL(ans)[0]);
>> UNPROTECT(1);
>> return(ans);
>> }
>>
>> Which compiles without problems into a shared library
>>
>> a1648:~ ivisser$ R CMD SHLIB -l
>> /Users/ivisser/Documents/projectsCurrent/dmm4Project/rfromc/
>> /Users/ivisser/Documents/projectsCurrent/dmm4Project/rfromc.c
>> gcc-4.0 -arch ppc -I/Library/Frameworks/R.framework/Resources/include
>> -I/Library/Frameworks/R.framework/Resources/include/ppc
>> -I/usr/local/include -fPIC -fno-common -g -O2 -std=gnu99 -c
>> /Users/ivisser/Documents/projectsCurrent/dmm4Project/rfromc.c -o
>> /Users/ivisser/Documents/projectsCurrent/dmm4Project/rfromc.o
>> gcc-4.0 -arch ppc -flat_namespace -bundle -undefined suppress
>> -L/usr/local/lib -o
>> /Users/ivisser/Documents/projectsCurrent/dmm4Project/rfromc.so
>> /Users/ivisser/Documents/projectsCurrent/dmm4Project/rfromc.o
>> -L/Library/Frameworks/R.framework/Resources/lib/ppc -lR
>>
>> And then call:
>>
>>> dyn.load("rfromc.so")
>>> .Call("doloop",nt)
>
> Try:
>
> .Call("doloop", as.integer(nt))
>
> I think nt probably is numeric but not integer; it is safer to impose the
> required storage mode than leave it to chance:
>
>> nt <- 1
>> storage.mode(nt)
> [1] "double"
>> .Call("doloop",nt)
> x: 0
> init ans: 0.000000
> [1] 0
>> .Call("doloop", as.integer(nt))
> x: 1
> init ans: 0.000000
> [1] 0
>> sessionInfo()
> Version 2.3.0 (2006-04-24)
> i686-pc-linux-gnu
>
> attached base packages:
> [1] "methods" "stats" "graphics" "grDevices" "utils" "datasets"
> [7] "base"
>
>
>
>>
>> With the following result (basically x is an unpredictable integer):
>>
>> x: 1072693248
>> init ans: 0.000000
>> [1] 0
>>
>> When I replace Rprintf("x: %d \n", x); with Rprintf("x: %f \n", x); (note
>> the %f) I get:
>>
>>> .Call("doloop",nt)
>> x: 1.000000
>> init ans: 0.000000
>> [1] 0
>>
>> Apparently x has the right value but is somehow represented as a double
>> instead of as integer
>>
>> I'm using:
>> Version 2.3.0 (2006-04-24)
>> powerpc-apple-darwin8.6.0
>>
>> attached base packages:
>> [1] "methods" "stats" "graphics" "grDevices" "utils" "datasets"
>> "base"
>>
>> Best, Ingmar
>>
>> ______________________________________________
>> R-help at stat.math.ethz.ch mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
>>
>
>
--
Brian D. Ripley, ripley at stats.ox.ac.uk
Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/
University of Oxford, Tel: +44 1865 272861 (self)
1 South Parks Road, +44 1865 272866 (PA)
Oxford OX1 3TG, UK Fax: +44 1865 272595
More information about the R-help
mailing list