Is it possible to catch error in C for Rf_eval R?

谁说胖子不能爱 提交于 2019-12-22 08:43:29

问题


I need to catch an error in Rf_eval in C. Is that even possible?

Some sample function

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

I have tried Rcpp_eval from Rcpp and Rcpp11, but both of them don't work for my case, I need to call Rf_eval directly. Is it possible to catch an error directly in C? If so how?


回答1:


use R_tryEval or R_tryEvalSilent in 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;
}

with

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

Here's a little more complete example, retrieving the last error

#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;
}

used as

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

Probably it makes a lot of sense to leave as much code as possible (e.g., conditional error handling) at the R level, either by wrapping the function to be evaluated or providing a custom error handling function instead of geterrmessage().



来源:https://stackoverflow.com/questions/27485899/is-it-possible-to-catch-error-in-c-for-rf-eval-r

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!