Hello,
I am not sure if I am interfacing with C correctly and _safely_
or if there is a better way esp. with regards to terminating
the "returned" array.
I am trying to fill an int array with values whose actual size
is determined in the C function and is always maximally as large
as length(values).
I also don't understand the purpose of $ab in the example:
conv <- function(a, b)
.C("convolve",
-snip-
ab = double(length(a) + length(b) - 1))$ab
void testFill(int *values, int *newvalues, int* endposition ){
newvalues[0] = 1;
newvalues[1] = 2;
*endposition = 2;
}
dyn.load("../testFill.so")
testTestFill <- function(){
tempfilled <- testFillC( c(30:40))
realfilled <- tempfilled$newvalues[1:tempfilled$endposition]
return(realfilled)
}
testFillC <- function(a){
.C("testFill", as.integer(a), newvalues=integer(length(a)),
endposition=integer(1))
}
Thank you very much in advance
Ido Tamir
correct C function usage
4 messages · Ido M. Tamir, Brian Ripley, Martin Maechler
On Tue, 13 Dec 2005, Ido M. Tamir wrote:
Hello, I am not sure if I am interfacing with C correctly and _safely_ or if there is a better way esp. with regards to terminating the "returned" array.
You need to pass the length to the C routine and check you do not overwrite it. (As in the parts you -snip-ed below.)
I am trying to fill an int array with values whose actual size
is determined in the C function and is always maximally as large
as length(values).
I also don't understand the purpose of $ab in the example:
conv <- function(a, b)
.C("convolve",
-snip-
ab = double(length(a) + length(b) - 1))$ab
.C returns a list, an element for each argument after the first, named if the arguments were named. So this selects the (copy) of the vector sent back as the last argument of the C function.
void testFill(int *values, int *newvalues, int* endposition ){
newvalues[0] = 1;
newvalues[1] = 2;
*endposition = 2;
}
dyn.load("../testFill.so")
testTestFill <- function(){
tempfilled <- testFillC( c(30:40))
realfilled <- tempfilled$newvalues[1:tempfilled$endposition]
return(realfilled)
}
testFillC <- function(a){
.C("testFill", as.integer(a), newvalues=integer(length(a)),
endposition=integer(1))
}
What do testFillC(1) or testFillC(logical(0)) do?
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
On Tuesday 13 December 2005 22:35, you wrote:
On Tue, 13 Dec 2005, Ido M. Tamir wrote:
Hello, I am not sure if I am interfacing with C correctly and _safely_ or if there is a better way esp. with regards to terminating the "returned" array.
You need to pass the length to the C routine and check you do not overwrite it. (As in the parts you -snip-ed below.)
testFillC <- function(a){
.C("testFill", as.integer(a), newvalues=integer(length(a)),
endposition=integer(1))
}
What do testFillC(1) or testFillC(logical(0)) do?
Thats undefined - probably a segmentation fault.
Thank you very much for your answers.
I was trying to cut down my actual function so readers could focus
on what I was seeing as the main problem: terminating the array.
I was hoping that somebody would tell me that I only have to terminate
the array in the C function somehow and the R part would recognize
that automagically - and no more passing lengths explicitly around and
copying arrays up to length - e.g (ignoring wrong arguments):
void testFill(int *values, int *newvalues ){
newvalues[0] = 1;
newvalues[1] = 2;
newvalues[2] = '\0';
}
testTestFill <- function(){
realfilled <- testFillC( 1:10 )
return(realfilled)
}
testFillC <- function(a){
.C("testFill", as.integer(a), newvalues=integer(length(a)))$newvalues
}
But I tried this and it does not help.
sincerely,
Ido Tamir
"Ido" == Ido M Tamir <tamir at imp.univie.ac.at>
on Wed, 14 Dec 2005 10:37:07 +0100 writes:
Ido> On Tuesday 13 December 2005 22:35, you wrote:
>> On Tue, 13 Dec 2005, Ido M. Tamir wrote:
>> > Hello,
>> > I am not sure if I am interfacing with C correctly and _safely_
>> > or if there is a better way esp. with regards to terminating
>> > the "returned" array.
>>
>> You need to pass the length to the C routine and check you do not
>> overwrite it. (As in the parts you -snip-ed below.)
>> > testFillC <- function(a){
>> > .C("testFill", as.integer(a), newvalues=integer(length(a)),
>> > endposition=integer(1))
>> > }
>>
>> What do testFillC(1) or testFillC(logical(0)) do?
Ido> Thats undefined - probably a segmentation fault.
Ido> Thank you very much for your answers.
Ido> I was trying to cut down my actual function so readers could focus
Ido> on what I was seeing as the main problem: terminating the array.
Ido> I was hoping that somebody would tell me that I only have to terminate
Ido> the array in the C function somehow and the R part would recognize
Ido> that automagically - and no more passing lengths explicitly around and
Ido> copying arrays up to length .............
Ido> .............
If you want this (and for other reasons),
the use of .Call() instead of .C() is highly recommended.
With .Call() you get proper "R objects" on the C side which you
can "interrogate" for LENGTH() but also any other attributes().
On return, the result of .Call() can be any R object you might
want to construct from C.
Doug Bates (and many others) has found this to be particularly
fruitful when working with S4 class objects.
And of course, that has been designed to work like this by John
Chambers himself at the time S4 was designed and "The Green
Book" was written. AFAIK, .Call() was part of the S4 wave
(with which I mean other innovations than just the S4 OO system).
Martin Maechler, ETH Zurich