Skip to content

Issue with c++ .C call

8 messages · Dominick Samperi, Thomas Lumley, Sean Davis

#
I am still having some difficulties with connecting R to a C++ function.  I
am able to call the function as expected after compiling the shared library
and such.  However, the call to the function is via .C; parameters from the
.C call are not being passed correctly to the function.  As an example, I
have attached a GDB run of the code.  I set a breakpoint on entry to the
function I am calling from R.  What is bothering me (and probably causing
the segmentation faults I am seeing) is that the parameter
prm=as.double(c(3.2,1.1)) is not 3.2,1.1 IMMEDIATELY after the call to .C.
I am sure I am missing something very basic.

Thanks,
Sean
R version 2.2.0, 2005-08-11, powerpc-apple-darwin7.9.0

attached base packages:
[1] "methods"   "stats"     "graphics"  "grDevices" "utils"     "datasets"
[7] "base"     




holmes:~/Mercury/projects/R/StepGram sdavis$ R -d gdb
GNU gdb 6.1-20040303 (Apple version gdb-413) (Wed May 18 10:17:02 GMT 2005)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "powerpc-apple-darwin"...Reading symbols for
shared libraries ... done

(gdb) r
Starting program: 
/Users/sdavis/R-devel2/R.framework/Versions/2.2.0/Resources/bin/exec/R
Reading symbols for shared libraries ...........+ done

R : Copyright 2005, The R Foundation for Statistical Computing
Version 2.2.0 Under development (unstable) (2005-08-11 r35256)
ISBN 3-900051-07-0

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for a HTML browser interface to help.
Type 'q()' to quit R.

Reading symbols for shared libraries
............................................................. done
Reading symbols for shared libraries . done
Reading symbols for shared libraries . done
Reading symbols for shared libraries .. done
vec <- c(thresh,noise)
  .C('calcStepgram',
     data=as.double(dat1),
     prm=as.double(vec),
     intervals=double(10000*3+1),
     max=as.integer(10000),
     n=as.integer(length(dat1)),
     plot=double(length(dat1)))}
3.2,3.1,-0.1,0.2,0.15,-0.05,-0.1,0.2,0.1,-0.1)
Program received signal SIGINT, Interrupt.
0x9001f208 in select ()
(gdb) break calcStepgram
Breakpoint 1 at 0x10bb418: file Stepgram.cpp, line 22.
(gdb) c
Continuing.
Breakpoint 1, calcStepgram (data=0x1137048, prm=0x1c81eb0,
intervals=0xbfffd7e0, max=0x2954840, n=0xbfffd6c0, plot=0x180d574) at
Stepgram.cpp:22
(gdb) print prm[0]
$1 = 1.7716149411915527e-303    <<<<<------This should be 3.2!
Current language:  auto; currently c++
#
Sean,

prm in your function calcStepgram is NOT a vector of doubles, it is of type
SEXP, and you need to use R macros to fetch the value(s). This is done
automatically in the Rcpp package, and if you want to see how this is
done look at the definition of the class RcppVector in Rcpp.cpp

Dominick
Sean Davis wrote:
#
On Tue, 10 Jan 2006, Dominick Samperi wrote:

            
Not at all.  He is using .C, which passes a double * to the C function. 
You may be thinking of .Call

 	-thomas
Thomas Lumley			Assoc. Professor, Biostatistics
tlumley at u.washington.edu	University of Washington, Seattle
#
On 1/10/06 1:41 PM, "Dominick Samperi" <dsamperi at DecisionSynergy.com> wrote:

            
I'm not sure why the prm parameter is not a vector; I thought this was the
standard way to create a vector of doubles....  So to confuse myself even
more, I have added a simple C function that looks simply calls my C++
function like this:

extern "C" {
  void mymain(double *data,double *prm, double* intervals, int* max, int *n,
double *plot) {
    calcStepgram(data,prm,intervals,max,n,plot);
  }
}

Then, I call this function using .C('mymain',...) as before.  Note the
change in parameter memory locations from the call to mymain and the call to
calcStepgram.  Why does this happen?
vec <- c(thresh,noise)
  .C('mymain',
     data=as.double(dat1),
     prm=as.double(vec),
     intervals=double(10000*3+1),
     max=as.integer(10000),
     n=as.integer(length(dat1)),
     plot=double(length(dat1)))}
3.1,3.2,3.1,-0.1,0.2,0.15,-0.05,-0.1,0.2,0.1,-0.1)

....

(gdb) break mymain
Breakpoint 1 at 0x10c13f0: file Stepgram.cpp, line 23.
(gdb) c
Continuing.
Breakpoint 1, mymain (data=0x1137148, prm=0x195cd30, intervals=0x1386018,
max=0x1b208e0, n=0x1b20900, plot=0x1137208) at Stepgram.cpp:23
23          calcStepgram(data,prm,intervals,max,n,plot);
(gdb) print prm[0]
$1 = 3
Current language:  auto; currently c++
(gdb) print prm[1]
$2 = 1
(gdb) print max[0]
$3 = 10000
(gdb) s       
calcStepgram (data=0x1137148, prm=0x180da24, intervals=0x195cd68,
max=0x1999d6c, n=0xbfffd6e0, plot=0x0) at Stepgram.cpp:29
29          Stepgram* sg=new Stepgram(data, *n);
(gdb) print prm[0]
$4 = 2.0002441518028817
(gdb)
#
On Tue, 10 Jan 2006, Sean Davis wrote:
Is this compiled with optimization? If so, you can't conclude much from 
the gdb info as the code can be executed in a different order from how 
it's written.

When I use this example

extern "C" void calcStepgram(double *data,  double *prm, double *intervals,
int *max, int *n,double *plot) {

  prm[0]=data[0];
  return;
}

if I compile with -g -02 (the default) it looks as though there are 
problems with initialization like the ones you report, but in fact the 
function works correctly.  If I compile without optimization the 
initialization looks fine.

 	-thomas
#
On 1/10/06 2:27 PM, "Thomas Lumley" <tlumley at u.washington.edu> wrote:

            
Thanks, Thomas.  That did fix the initialization issue (or apparent one).
Unfortunately, the reason that I started debugging was for segmentation
faults, which have not gone away.  However, it now looks like the problem is
internal to the C++ code and not with the way the arguments were being
passed.  

Back to gdb....

Sean
#
On Tue, 10 Jan 2006, Sean Davis wrote:

            
If you can get access to a Linux machine then it's worth trying Valgrind, 
which is very helpful for this sort of thing.

 	-thomas
#
On 1/10/06 6:50 PM, "Thomas Lumley" <tlumley at u.washington.edu> wrote:

            
I'm going to improve my access, just for this sort of thing.

The problem turned out to be a commented out line in the original C++ code
that wasn't manifesting itself all the time in the standalone code, but was
under R.  So, while the error was hard to find, it was easy to fix.

Thanks to Thomas, Robert Gentleman, Dominick Samperi, and Brian Ripley for
their patient help.

Sean