Skip to content

[Rcpp-devel] Accessing T of RcppVector<T>

5 messages · Groß, Sebastian, Dirk Eddelbuettel, Johannes Egner

#
Hey there,
 
At first please forgive my intrusion into your high level development
conversation. But some, in my opinion rather weird, thing occured to me while
using the RcppVector class.
Maybe it just appears somewhat cloudy to me due to my lack of firm c++
programming experience.
To not to beat around the bush the topic is following.
I try to call a c++ function expecting a double as parameter. The parameter
is brought to the function via an R SEXP which I interprete as an
RcppVector<double>.
Obviously in case the SEXP contains just one single double value one can
access it using the operator(int i).
According to the signature of RcppVector<T>(int i) the result will be T&,
especially in my case double&.
That is exactly the point where I don't know how to proceed.
 
Refering to my rudimentary c knowledge, double& means the adress of a double
value so I have to access the value by using the derefering operator *, but
this does not work, I always get the gcc error: invalid argument to unary
'*'. And not using the * operator leads to the error of not matching a
candidate signature of the function I call.
 
In case a simplified code sample helps to understand what I intend to do:
 
in R
 
real_num <- 42.1337
tmp <- .call("func", real_num, "package=mypackage")
 
in C++
 
RcppExport SEXP func(SEXP real_num)
{
     //create the vector
     RcppVector<double> tmp(real_num);
 
     //access its one and only element and call the function
    other(tmp(0));
 
     //does not work, at least not in my environment
}
 
void other(double any_double)
{
     cout << "YAY it works" << endl;
}
 
I would be very thankful to any advise, information, or tip in the right
direction where to search to achieve further knowledge beyond RTFM and STFW
which I did in plenty of ways
 
 
Cheers and Thanks in advance
 
Sebastian
#
Hi Sebastian,

You are doing a few things in a rather awkward manner.  One thing is that you
still stick to what we call the 'classic' API; most of us think you probably
want the newer one.  Have another look at the Rcpp-introduction vignette in
Rcpp 0.8.7 (maybe via the CRAN website). Also some of your R assignments
were, well, wrong as you were a little generous with the <-. 

With that, here is a simple example using Rcpp and inline.

First, I (re-)define your helper function, making the argument const:
+            std::cout << "YAY it works, value is " << any << std::endl;
+         }
+        '
Next, the body of the function.  We get a double, once as a vector (which
will have length 1 of we pass a scalar as we do here -- recall that
everything is a vector in R) and once as a double.
+         double dbl = Rcpp::as<double>(x);                  // as double
+         other(vec(0));
+         other(dbl);
+         return Rcpp::wrap(0);
+        '
We then make this a function in R using cxxfunction from inline:
+                    body=src, inc=inc, plugin="Rcpp")
And use it:
YAY it works, value is 42.1337
YAY it works, value is 42.1337
[1] 0
YAY it works, value is 3.1415
YAY it works, value is 3.1415
[1] 0
For reference, the whole code is again below.

Hope this helps, Dirk



## define our helper function, this will be passed as an include segment to cxxfunction()
inc <- 'void other(const double any) {
           std::cout << "YAY it works, value is " << any << std::endl;
        }
       '

## body of function: get scalar two different way, use it
src <- 'Rcpp::NumericVector vec = Rcpp::NumericVector(x);  // as vector
        double dbl = Rcpp::as<double>(x);                  // as double
        other(vec(0));
        other(dbl);
        return Rcpp::wrap(0);
       '


library(inline)
fun <- cxxfunction(signature(x="numeric"),
                   body=src, inc=inc, plugin="Rcpp")


num <- 42.1337
fun(num)
fun(3.1415)
1 day later
#
Dirk's code relates to a question I meant to ask the experts for a while:
what's a safe and generic way to print C/C++ objects in an R session?

The background: forwarding the cout-stream in Dirk's example to R as below
doesn't work in the R-GUI on Windows (or in an IDE such as Eclipse); but it
does work if one runs an R session from the command line (that is, within
the console -- no surprise that the stream is correctly forwarded).

Additionally, there's a (confusing) variety of other print-functions that
successfully bridge the gap between C functions and the R-GUI, mostly made
available through prtutil.h. For instance, Rf_PrintValue takes an SEXP and
prints it to R using the "right format" when used in any C/C++-function,
whereas functions such as Rf_printIntegerVector  take C arguments (and
somehow smuggle them into the R session). And then there's the workhorse
Rprintf (which is possibly called by Rf_printIntegerVector).

Apologies for being so vague -- I would say I am eventually looking for a
way to make the below example run in the R-GUI, both to avoid using the
abovementioned functions, and to use existing C++-code that contains
summary/debugging overloads of cout. (This may belong to Rd and not to
Rcpp-devel, but I'm not sure.)

Best, Jo



2010/10/28 Dirk Eddelbuettel <edd at debian.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20101030/c26ab56d/attachment.htm>
#
I was imprecise here: it does work using the Rterm connector in
Eclipse/StatET, but not with the RJ-connector. (For those who use this IDE.)

It seems to boild down to contingent (and annoying) implementation details
that are far beyond Rcpp's control -- I suspect my question really doesn't
belong here.

Jo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20101030/dadf5db1/attachment.htm>
#
On 30 October 2010 at 13:02, Johannes Egner wrote:
| > The background: forwarding the cout-stream in Dirk's example to R as below
| > doesn't work in the R-GUI on Windows (or in an IDE such as Eclipse); but it
| > does work if one runs an R session from the command line (that is, within
| > the console -- no surprise that the stream is correctly forwarded).
| >
| 
| I was imprecise here: it does work using the Rterm connector in
| Eclipse/StatET, but not with the RJ-connector. (For those who use this IDE.)
| 
| It seems to boild down to contingent (and annoying) implementation details
| that are far beyond Rcpp's control -- I suspect my question really doesn't
| belong here.

I would agree :)  Rcpp does not special here --- we not define or redefine
anything related to input/output.  

And the "Writing R Extensions" manual clearly states it:

   5.6 Interfacing C++ code
   ========================
   
   [...]
   
      Using C++ iostreams, as in this example, is best avoided.  There is
   no guarantee that the output will appear in the R console, and indeed it
   will not on the R for Windows console.  Use R code or the C entry points
   (*note Printing::) for all I/O if at all possible.

so the line you were referring to actually came from simple debugging output,
and was authored by Sebastian to whom I replied with a fix.

So in short: if you must print, use Rprintf, or REprintf for stderr, as
detailed in section "6.5 Printing" of Writing R Extensions.

Regards, Dirk