从C计算R命令无效
我正在尝试制作简单的R命令计算器 我有以下代码: 评估员从C计算R命令无效,r,R,我正在尝试制作简单的R命令计算器 我有以下代码: 评估员 void evaluate(const std::string &command); extern "C" SEXP run_eval() { evaluate("grDevices:::png(\"snapshot.png\")"); return R_NilValue; } Evaluator.cpp SEXP createSexp(const std::string &str, ScopeProtect
void evaluate(const std::string &command);
extern "C" SEXP run_eval() {
evaluate("grDevices:::png(\"snapshot.png\")");
return R_NilValue;
}
Evaluator.cpp
SEXP createSexp(const std::string &str, ScopeProtector *protector) {
SEXP result = Rf_allocVector(STRSXP, 1);
protector->add(result);
SET_STRING_ELT(result, 0, Rf_mkChar(str.c_str()));
return result;
}
SEXP createExpressionSexp(SEXP strSexp, ScopeProtector *protector) {
ParseStatus status;
SEXP result = R_ParseVector(strSexp, 1, &status, R_NilValue);
protector->add(result);
return result;
}
SEXP createExpressionSexp(const std::string &str, ScopeProtector *protector) {
return createExpressionSexp(createSexp(str, protector), protector);
}
SEXP evaluateExpression(SEXP exprSexp, ScopeProtector *protector) {
SEXP result = Rf_eval(exprSexp, R_GlobalEnv);
protector->add(result);
return result;
}
void evaluate(const std::string &command) {
ScopeProtector protector;
evaluateExpression(createExpressionSexp(command, &protector), &protector);
}
范围保护器
class ScopeProtector: boost::noncopyable {
public:
ScopeProtector();
virtual ~ScopeProtector();
void add(SEXP sexp);
private:
class Impl;
const std::unique_ptr<Impl> pImpl;
};
CMakeLists.txt
cmake_minimum_required(VERSION 3.3)
project(REvaluator)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Werror")
include_directories("/usr/share/R/include")
set(
SOURCE_FILES
Evaluator.cpp Evaluator.h
ScopeProtector.cpp ScopeProtector.h
)
add_library(revaluator SHARED ${SOURCE_FILES})
我试图通过执行以下命令来检查我的计算器:
> dyn.load("librevaluator.so")
> .Call("run_eval")
NULL
> dev.list()
NULL
正如您所见,没有任何png设备。你能告诉我问题出在哪里吗?你看过它的Rcpp::Function()
我们通常不建议从“C++中的低端”调用大量的R函数,但对于创建图形设备这样的偶然设置问题,这是非常好的
(请注意,我缩进了代码以适应这里的显示。
cppFunction()
是一行;它使用参数中定义的函数创建了一个共享库,并分配了它——这样我们刚刚创建的新R调用者newDev
就可以用来创建png设备。)我找到了解决方案。替换
SEXP result = Rf_eval(exprSexp, R_GlobalEnv);
与
Rcpp是否包含在std R发行版中,还是应该手动安装?@user2235698您可以随时使用
installed.packages()
@Tim来检查是否已经安装了某些内容。我想编写一个计算器,它可以与任何R一起使用installation@user2235698Rcpp是最简单和推荐的(例如)方法。如果你想,你可以使用纯C++,但为什么你愿意麻烦重新发明车轮…?许多主要软件包都链接到Rcpp,因此大多数用户可能已经安装了Rcpp。
R> library(Rcpp)
R> dev.list()
NULL
R> cppFunction('void newDev(std::string filename) {
Rcpp::Function dn = Rcpp::Function("png");
dn(filename); }')
R> newDev("/tmp/foo.png")
R> dev.list()
png
2
R>
SEXP result = Rf_eval(exprSexp, R_GlobalEnv);
SEXP result = Rf_eval(VECTOR_ELT(exprSexp, 0), R_GlobalEnv);