2011-12-08 48 views
7

Tôi đang cố gắng báo cáo lỗi từ mã rcpp của mình. Tôi đang sử dụng hàm tạo exception (const char *message_, const char *file, int line) từ http://dirk.eddelbuettel.com/code/rcpp/html/classRcpp_1_1exception.html. Để cô lập các vấn đề, tôi đã viết như sau bar.cpp:Tăng ngoại lệ trong Rcpp

#include <Rcpp.h> 

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

Khi tôi chạy nó trong R, đây là những gì tôi nhận được:

> 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' 
> 

Trả lời

5

Bạn có thể

  • sử dụng Gói inline đặt khối try/catch vào hàm mà nó tạo cho bạn (bằng cách sử dụng hai macro đơn giản)

  • hoặc làm nó bằng tay mình như thể hiện trong một loạt các ví dụ trên blog của tôi, hoặc trong các ví dụ/phần của gói Rcpp,

nhưng làm những gì bạn (ví dụ: ném bên ngoài của một thử/catch block) không bao giờ có thể hoạt động.

Là một tiền thưởng thêm, đây là một ví dụ hoàn chỉnh (trong đó chủ yếu đã tồn tại trong các bài kiểm tra đơn vị):

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> 

Một lần nữa, cxxfunction() đặt một khối try/catch() ở đây để bạn như bạn có thể thấy nếu bạn bật verbose trên:

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> 

các BEGIN_RCPPEND_CPP thêm sự kỳ diệu bạn cần ở đây.

Vui lòng làm chuyển câu hỏi của bạn sang rcpp-devel.

+0

Cảm ơn! từ các ví dụ, bạn có nghĩa là 'copyMessageToR' và' Rf_error' như được sử dụng trong RcppDateExample.cpp? Tôi không thể tìm thấy tài liệu cho 'copyMessageToR'. – highBandWidth

+0

Aah ... nhưng yêu cầu ở đây dường như chỉ hoạt động tốt, mang lại câu trả lời tuyệt vời trong vòng vài phút, sau khi tất cả! Bắt trôi dạt của tôi? ;) –

+0

Có. Đó là những gì bạn sử dụng trong khối 'catch()'. –

3

Chỉ cần quấn mã của bạn bên BEGIN_RCPP/END_RCPP:

RcppExport SEXP bar(SEXP x){ 
BEGIN_RCPP 

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

END_RCPP 
} 

Lưu ý rằng bạn có thể ném ngoại lệ std bình thường quá:

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

Ngay cả sau khi thêm 'BEGIN_RCPP' và' END_RCPP', 'Rcpp :: exception' vẫn cho cùng một lỗi' STL_VECTOR_ELT'. 'std :: invalid_argument' ném một ngoại lệ, nhưng thông điệp được hiển thị trong R là một lỗi chung: Lỗi: C++ exception (lý do không xác định)'. – highBandWidth

Các vấn đề liên quan