This is maybe better suited for Rcpp-devel or another mailing list. If so,
I apologize. :-)
In a pet project I've been implementing quite a bit of a package structure
within Cpp, including classes to contain and manipulate structures. As a
final part of the implementation a user provided R function is to be
executed with some of the manipulated data. While my first intuition (and
the smart option) was to implement a method in R for extracting the
parameters and simply executing the call, I got curious as to how one could
do this in Cpp.
After researching I found myriad options, one simple method being
1) Create a list of named and unnamed arguments
2) Extract "do.call" as a Function,
3) Test that the function provided is either a CLOSXP (function) or CHARSXP
(or maybe STRSXP?) and then
4) execute the function call.
but while going further down and checking the source code for do_docall I
was curious about trying to recreate the call "the old fashioned way", but
in Cpp. After looking over how it was done in R-source and a few examples
online I tried implementing a simple call creation and evaluating it with
Rf_eval
```cpp
#include <R.h>
#include <Rinternals.h>
//[[Rcpp::export]]
SEXP add_10_and_5(SEXP rho){ //rho is an environment (new.env() here)
SEXP REALSXP_10 = PROTECT(ScalarReal(10));
SEXP REALSXP_5 = PROTECT(ScalarReal(5));
SEXP out = PROTECT(LCONS(install("+"), LCONS(
REALSXP_10, LCONS(
REALSXP_5, R_NilValue
)
)));
UNPROTECT(3);
return eval(out, rho);
}
```
(For those who read the old version of Advanced R, this is a very similar
to the R's C interface section on "PairLists")
Immediately intellisense warned me that "ScalarReal", "install", "lcons"
and "eval" are all undefined. However, a quick look in
src/include/Rinternals.h shows that they are forward-declared there, and
should (in my understanding) be defined. For good measures I tried
including every header iteratively to no avail.
While it is likely recommended to not do this (and the final product likely
will be implemented in R), I am curious why I seem unable to access these 4
from Cpp. I can't seem to spot the reason in the header file itself.
Best regards
Oliver
[R-pkg-devel] accessing call constructors in Cpp
3 messages · Bill Dunlap, Oliver Madsen
Try using their official names, Rf_ScalarReal, Rf_eval, Rf_install, etc. You may have #defined R_NO_REMAP in code that you did not show us. -Bill On Tue, Jan 5, 2021 at 1:42 PM Oliver Madsen <oliver.p.madsen at gmail.com> wrote:
This is maybe better suited for Rcpp-devel or another mailing list. If so,
I apologize. :-)
In a pet project I've been implementing quite a bit of a package structure
within Cpp, including classes to contain and manipulate structures. As a
final part of the implementation a user provided R function is to be
executed with some of the manipulated data. While my first intuition (and
the smart option) was to implement a method in R for extracting the
parameters and simply executing the call, I got curious as to how one could
do this in Cpp.
After researching I found myriad options, one simple method being
1) Create a list of named and unnamed arguments
2) Extract "do.call" as a Function,
3) Test that the function provided is either a CLOSXP (function) or CHARSXP
(or maybe STRSXP?) and then
4) execute the function call.
but while going further down and checking the source code for do_docall I
was curious about trying to recreate the call "the old fashioned way", but
in Cpp. After looking over how it was done in R-source and a few examples
online I tried implementing a simple call creation and evaluating it with
Rf_eval
```cpp
#include <R.h>
#include <Rinternals.h>
//[[Rcpp::export]]
SEXP add_10_and_5(SEXP rho){ //rho is an environment (new.env() here)
SEXP REALSXP_10 = PROTECT(ScalarReal(10));
SEXP REALSXP_5 = PROTECT(ScalarReal(5));
SEXP out = PROTECT(LCONS(install("+"), LCONS(
REALSXP_10, LCONS(
REALSXP_5, R_NilValue
)
)));
UNPROTECT(3);
return eval(out, rho);
}
```
(For those who read the old version of Advanced R, this is a very similar
to the R's C interface section on "PairLists")
Immediately intellisense warned me that "ScalarReal", "install", "lcons"
and "eval" are all undefined. However, a quick look in
src/include/Rinternals.h shows that they are forward-declared there, and
should (in my understanding) be defined. For good measures I tried
including every header iteratively to no avail.
While it is likely recommended to not do this (and the final product likely
will be implemented in R), I am curious why I seem unable to access these 4
from Cpp. I can't seem to spot the reason in the header file itself.
Best regards
Oliver
[[alternative HTML version deleted]]
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
Hi Bill thanks for your answer, The only part left out (which I only realized as I'm trying out your suggestion) is an #include Rcpp in order to remove 5 errors thrown when executing Rcpp::sourceCpp. I am guessing that the suggestion from RAPI to always work with R_NO_REMAP defined is taken literally and that it is defined in Rcpp.h or its dependencies. But it is working, thank you! :-) (continues to dive further down the rabbit hole) Best Regards Oliver On Wed, Jan 6, 2021 at 12:01 AM Bill Dunlap <williamwdunlap at gmail.com> wrote:
Try using their official names, Rf_ScalarReal, Rf_eval, Rf_install, etc. You may have #defined R_NO_REMAP in code that you did not show us. -Bill On Tue, Jan 5, 2021 at 1:42 PM Oliver Madsen <oliver.p.madsen at gmail.com> wrote:
This is maybe better suited for Rcpp-devel or another mailing list. If so,
I apologize. :-)
In a pet project I've been implementing quite a bit of a package structure
within Cpp, including classes to contain and manipulate structures. As a
final part of the implementation a user provided R function is to be
executed with some of the manipulated data. While my first intuition (and
the smart option) was to implement a method in R for extracting the
parameters and simply executing the call, I got curious as to how one
could
do this in Cpp.
After researching I found myriad options, one simple method being
1) Create a list of named and unnamed arguments
2) Extract "do.call" as a Function,
3) Test that the function provided is either a CLOSXP (function) or
CHARSXP
(or maybe STRSXP?) and then
4) execute the function call.
but while going further down and checking the source code for do_docall I
was curious about trying to recreate the call "the old fashioned way", but
in Cpp. After looking over how it was done in R-source and a few examples
online I tried implementing a simple call creation and evaluating it with
Rf_eval
```cpp
#include <R.h>
#include <Rinternals.h>
//[[Rcpp::export]]
SEXP add_10_and_5(SEXP rho){ //rho is an environment (new.env() here)
SEXP REALSXP_10 = PROTECT(ScalarReal(10));
SEXP REALSXP_5 = PROTECT(ScalarReal(5));
SEXP out = PROTECT(LCONS(install("+"), LCONS(
REALSXP_10, LCONS(
REALSXP_5, R_NilValue
)
)));
UNPROTECT(3);
return eval(out, rho);
}
```
(For those who read the old version of Advanced R, this is a very similar
to the R's C interface section on "PairLists")
Immediately intellisense warned me that "ScalarReal", "install", "lcons"
and "eval" are all undefined. However, a quick look in
src/include/Rinternals.h shows that they are forward-declared there, and
should (in my understanding) be defined. For good measures I tried
including every header iteratively to no avail.
While it is likely recommended to not do this (and the final product
likely
will be implemented in R), I am curious why I seem unable to access these
4
from Cpp. I can't seem to spot the reason in the header file itself.
Best regards
Oliver
[[alternative HTML version deleted]]
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel