是否有可能在C中捕获Rf_eval R的错误?

Rom*_*kyi 4 c r try-catch

我需要捕捉的错误Rf_evalC.这甚至可能吗?

一些样本功能

SEXP foo(SEXP x, SEXP env) {
   SEXP res;
   PROTECT(res = Rf_eval(x, env));
   UNPROTECT(1); 
   return res;
}
Run Code Online (Sandbox Code Playgroud)

我试图Rcpp_evalRcppRcpp11,但他们都没有为我的情况下工作,我需要调用Rf_eval直接.是否有可能直接在C中捕获错误?如果是这样的话?

Mar*_*gan 5

在Rinternals.h中使用R_tryEval或R_tryEvalSilent

#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;
}
Run Code Online (Sandbox Code Playgroud)

> .Call("foo", quote(stop("oops")), .GlobalEnv)
Error: oops
error occurred
NULL
Run Code Online (Sandbox Code Playgroud)

这是一个更完整的示例,检索最后一个错误

#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;
}
Run Code Online (Sandbox Code Playgroud)

用作

.Call("silent", quote(stop("oops")), .GlobalEnv, quote(geterrmessage()))
Run Code Online (Sandbox Code Playgroud)

在R级别保留尽可能多的代码(例如,条件错误处理)可能很有意义,无论是通过包装要评估的函数还是提供自定义错误处理函数而不是geterrmessage().