Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从C代码发出R异常信号_C_R - Fatal编程技术网

如何从C代码发出R异常信号

如何从C代码发出R异常信号,c,r,C,R,R中的stop函数可以通过list对象调用,以表示特定类型的异常。例如,要发出foo异常信号,我们可以执行以下操作: foo <- list ( message = "my foo error" ) class(foo) <- c("foo", "condition") tryCatch ( stop(foo), foo = function(e){"never mind foo."} ) fo C++中如何实现它的一个标准例子是 仅对第一部分进行一次小编辑: #

R中的
stop
函数可以通过list对象调用,以表示特定类型的异常。例如,要发出
foo
异常信号,我们可以执行以下操作:

foo <- list (
  message = "my foo error"
)
class(foo) <- c("foo", "condition")

tryCatch (
  stop(foo), 
  foo = function(e){"never mind foo."}
)

<代码> fo C++中如何实现它的一个标准例子是

仅对第一部分进行一次小编辑:

#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
double takeLog(double val) {
    try {
        if (val <= 0.0) {           // log() not defined here
            throw std::range_error("Inadmissible value");
        }
        return log(val);
    } catch(std::exception &ex) {   
        forward_exception_to_r(ex);
    } catch(...) { 
        stop("c++ exception (unknown reason)"); 
    }
    return NA_REAL;             // not reached
}

其余的帖子有一些细节。

< P> C++中的一个标准例子是:

仅对第一部分进行一次小编辑:

#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
double takeLog(double val) {
    try {
        if (val <= 0.0) {           // log() not defined here
            throw std::range_error("Inadmissible value");
        }
        return log(val);
    } catch(std::exception &ex) {   
        forward_exception_to_r(ex);
    } catch(...) { 
        stop("c++ exception (unknown reason)"); 
    }
    return NA_REAL;             // not reached
}

这篇文章的其余部分有一些细节。

基于上述建议,我编写了这个函数,它满足了我的需要:

void signal_exception(const char* message, const char* condition){
  //the condition object
  SEXP vec = PROTECT(allocVector(VECSXP, 1));
  SET_VECTOR_ELT(vec, 0, mkString(message));
  setAttrib(vec, R_NamesSymbol, mkString("message"));

  //the class vector
  SEXP cls = PROTECT(allocVector(STRSXP, 3));
  SET_STRING_ELT(cls, 0, mkChar(condition));
  SET_STRING_ELT(cls, 1, mkChar("error"));
  SET_STRING_ELT(cls, 2, mkChar("condition"));
  setAttrib(vec, R_ClassSymbol, cls);

  //signal the condition by calling base::stop
  SEXP stop_sym  = PROTECT(Rf_install("stop"));
  SEXP call = PROTECT(Rf_lang2(stop_sym, vec));
  UNPROTECT(4);
  Rf_eval(call, R_GlobalEnv);
}
它基本上用第二个参数概括了
Rf_error
,您可以使用该参数指定错误的类别


我认为从C调用
base::stop
并不是一件很优雅的事情,只是让它调用
.Internal(.signalCondition())
,但我认为目前似乎没有API可以直接从C发出条件信号。

基于上述建议,我编写了这个函数,它满足了我的需要:

void signal_exception(const char* message, const char* condition){
  //the condition object
  SEXP vec = PROTECT(allocVector(VECSXP, 1));
  SET_VECTOR_ELT(vec, 0, mkString(message));
  setAttrib(vec, R_NamesSymbol, mkString("message"));

  //the class vector
  SEXP cls = PROTECT(allocVector(STRSXP, 3));
  SET_STRING_ELT(cls, 0, mkChar(condition));
  SET_STRING_ELT(cls, 1, mkChar("error"));
  SET_STRING_ELT(cls, 2, mkChar("condition"));
  setAttrib(vec, R_ClassSymbol, cls);

  //signal the condition by calling base::stop
  SEXP stop_sym  = PROTECT(Rf_install("stop"));
  SEXP call = PROTECT(Rf_lang2(stop_sym, vec));
  UNPROTECT(4);
  Rf_eval(call, R_GlobalEnv);
}
它基本上用第二个参数概括了
Rf_error
,您可以使用该参数指定错误的类别


我认为从C调用
base::stop
并不是一件很优雅的事情,只是让它调用
.Internal(.signalCondition())
,但我认为目前似乎没有API可以直接从C发出条件信号。

C++有异常,C没有。因此,如果你想要异常,使用C++。你可以从C调用<代码>停止<代码>,而不是<代码> RfOrthys。C++有例外,C没有。所以,如果你想要异常,使用C++。你可以从C调用<代码>停止<代码>,而不是<代码> RfOrthys。谢谢。我想答案应该在
forward\u exception\u to\u r
的源代码中。这里没有太大的魔力,它基本上只是调用
stop()
的,参见这里的示例谢谢。我想答案应该在
forward\u exception\u to\u r
的源代码中。这里没有太大的魔力,它基本上只是调用
stop()
的,参见这里的示例