2014-12-15 5 views
4

Мне нужно поймать ошибку в Rf_eval в C. Возможно ли это?Возможно ли уловить ошибку в C для Rf_eval R?

Некоторые функции образца

SEXP foo(SEXP x, SEXP env) { 
    SEXP res; 
    PROTECT(res = Rf_eval(x, env)); 
    UNPROTECT(1); 
    return res; 
} 

Я попытался Rcpp_eval от Rcpp и Rcpp11, но оба они не работают в моем случае, мне нужно позвонить Rf_eval напрямую. Можно ли поймать ошибку непосредственно в C? Если да, то как?

ответ

5

использование R_tryEval или R_tryEvalSilent в Rinternals.h

#include <Rdefines.h> 

SEXP foo(SEXP fun, SEXP env) 
{ 
    int err = 0; 
    R_tryEval(fun, env, &err); 
    if (err) 
     Rprintf("error occurred\n"); 
    return R_NilValue; 
} 

с

> .Call("foo", quote(stop("oops")), .GlobalEnv) 
Error: oops 
error occurred 
NULL 

Вот немного более полный пример, получение последней ошибки

#include <Rdefines.h> 

SEXP silent(SEXP fun, SEXP env, SEXP errmsg) 
{ 
    int err = 0; 
    SEXP result = PROTECT(R_tryEvalSilent(fun, env, &err)); 
    if (err) { 
     SEXP msg = PROTECT(R_tryEvalSilent(errmsg, env, &err)); 
     if (!err) 
      Rprintf("error occurred: %s", 
        CHAR(STRING_ELT(msg, 0))); 
     else 
      Rprintf("(unknown) error occurred"); 
     UNPROTECT(1); 
     result = R_NilValue; 
    } 

    UNPROTECT(1); 
    return result; 
} 

используется в качестве

.Call("silent", quote(stop("oops")), .GlobalEnv, quote(geterrmessage())) 

Возможно, имеет смысл оставить как можно больше кода (например, условную обработку ошибок) на уровне R, либо путем обнуления функции, которую нужно оценить, либо предоставления пользовательской функции обработки ошибок вместо geterrmessage().

+0

Спасибо. Это сработало –