Raising exceptions in Rcpp

跟風遠走 提交于 2019-12-10 03:30:20

问题


I am trying to report errors from my rcpp code. I am using the constructor exception (const char *message_, const char *file, int line) from http://dirk.eddelbuettel.com/code/rcpp/html/classRcpp_1_1exception.html. To isolate the problem, I wrote the following bar.cpp:

#include <Rcpp.h>

RcppExport SEXP bar( SEXP x){
        throw(Rcpp::exception("My Error Message","bar.cpp",4));
        return x ;
}

When I run it in R, this is what I get:

> dyn.load("bar.so")
> is.loaded("bar")
[1] TRUE
> .Call("bar",12)
Error: SET_VECTOR_ELT() can only be applied to a 'list', not a 'NULL'
> 

回答1:


You can either

  • use the inline package which puts a try/catch block into the function it generates for you (by using two simple macros)

  • or do it manually yourself as shown in a bunch of examples on my blog, or in the examples/ section of the Rcpp package,

but doing what you (ie: throwing outside of a try/catch block) can never work.

As an added bonus, here is a complete example (which essentially already existed in the unit tests):

R> library(inline)
R> f <- cxxfunction(signature(), plugin="Rcpp", body='
+    throw std::range_error("boom");
+    return R_NilValue;
+ ')
R> f()
Error in f() : boom
R>

Again, cxxfunction() puts a try/catch() block in here for you as you can see if you turn verbose on:

R> f <- cxxfunction(signature(), plugin="Rcpp", body='
+    throw std::range_error("boom");
+    return R_NilValue;
+ ', verbose=TRUE)
 >> setting environment variables:
PKG_LIBS =  -L/usr/local/lib/R/site-library/Rcpp/lib \
            -lRcpp -Wl,-rpath,/usr/local/lib/R/site-library/Rcpp/lib

 >> LinkingTo : Rcpp
CLINK_CPPFLAGS =  -I"/usr/local/lib/R/site-library/Rcpp/include"

 >> Program source :

   1 :
   2 : // includes from the plugin
   3 :
   4 : #include <Rcpp.h>
   5 :
   6 :
   7 : #ifndef BEGIN_RCPP
   8 : #define BEGIN_RCPP
   9 : #endif
  10 :
  11 : #ifndef END_RCPP
  12 : #define END_RCPP
  13 : #endif
  14 :
  15 : using namespace Rcpp;
  16 :
  17 :
  18 :
  19 : // user includes
  20 :
  21 :
  22 : // declarations
  23 : extern "C" {
  24 : SEXP file4cc53282( ) ;
  25 : }
  26 :
  27 : // definition
  28 :
  29 : SEXP file4cc53282(  ){
  30 : BEGIN_RCPP
  31 :
  32 :    throw std::range_error("boom");
  33 :    return R_NilValue;
  34 :
  35 : END_RCPP
  36 : }
  37 :
  38 :
Compilation argument:
 /usr/lib/R/bin/R CMD SHLIB file4cc53282.cpp 2> file4cc53282.cpp.err.txt
ccache g++-4.6 -I/usr/share/R/include   \
   -I"/usr/local/lib/R/site-library/Rcpp/include"   \
   -fpic  -g0 -O3 -Wall -pipe -Wno-unused -pedantic -c file4cc53282.cpp \
   -o file4cc53282.o
g++ -shared -o file4cc53282.so file4cc53282.o \
   -L/usr/local/lib/R/site-library/Rcpp/lib \
   -lRcpp -Wl,-rpath,/usr/local/lib/R/site-library/Rcpp/lib \
   -L/usr/lib/R/lib -lR
R>

The BEGIN_RCPP and END_CPP add the magic you need here.

Please do move your questions to rcpp-devel.




回答2:


Just wrap your code inside BEGIN_RCPP/END_RCPP:

RcppExport SEXP bar( SEXP x){
BEGIN_RCPP

        throw(Rcpp::exception("My Error Message","bar.cpp",4));
        return x ;

END_RCPP
}

Note that you can throw normal std exceptions too:

throw std::invalid_argument("'x' is too short");


来源:https://stackoverflow.com/questions/8438701/raising-exceptions-in-rcpp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!