是否有可能在C中捕获Rf_eval R的错误?
我需要在C
捕获Rf_eval
中的错误。 这有可能吗?
一些样本function
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中捕获错误? 如果是这样的话?
在Rinternals.h中使用R_tryEval或R_tryEvalSilent
#include 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 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()))
通过包装要评估的函数或提供自定义error handling函数而不是geterrmessage()
,在R级别留下尽可能多的代码(例如,条件error handling)可能geterrmessage()
。