如何从C代码发出R异常信号
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++中如何实现它的一个标准例子是 仅对第一部分进行一次小编辑: #
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()
的,参见这里的示例