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

时间:2014-12-15 14:08:42

标签: c r try-catch

我需要在Rf_eval的{​​{1}}中发现错误。这甚至可能吗?

一些示例功能

C

我已尝试SEXP foo(SEXP x, SEXP env) { SEXP res; PROTECT(res = Rf_eval(x, env)); UNPROTECT(1); return res; } Rcpp_eval中的Rcpp,但两者都不适合我的情况,我需要直接致电Rcpp11。是否有可能直接在C中捕获错误?如果是这样的话?

1 个答案:

答案 0 :(得分: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;
}

> .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()))

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