c++ - 混合 Rcpp 模块和 Rcpp::export

标签 c++ r rcpp

我想公开一个 C++ 类和一个将该类的对象作为 R 参数的函数。我必须遵循简化的示例。我使用创建了一个包

Rscript -e 'Rcpp::Rcpp.package.skeleton("soq")'
并将以下代码放入 soq_types.h
#include <RcppCommon.h>
#include <string>

class Echo {
  private:
  std::string message;
  public:
  Echo(std::string message) : message(message) {}
  Echo(SEXP);

  std::string get() { return message; }
};

#include <Rcpp.h>

using namespace Rcpp;

RCPP_MODULE(echo_module) {
  class_<Echo>("Echo")
  .constructor<std::string>()
  .method("get", &Echo::get)
  ;
};

//// [[Rcpp::export]]
void shout(Echo e) {
  Rcout << e.get() << "!" << std::endl;
}
请注意,最后一条注释有额外的斜杠,不会导致函数被导出。当我现在运行时:
$> Rscript -e 'Rcpp::compileAttributes()'
$> R CMD INSTALL .

R> library(Rcpp)
R> suppressMessages(library(inline))
R> library(soq)
R> echo_module <- Module("echo_module", getDynLib("soq"))
R> Echo <- echo_module$Echo
R> e <- new(Echo, "Hello World")
R> print(e$get())
一切安好。不幸的是,如果我启用 Rcpp::export , 做 compileAttributes()并重新安装我得到:
** testing if installed package can be loaded from temporary location
Error: package or namespace load failed for ‘soq’ in dyn.load(file, DLLpath = DLLpath, ...):
 unable to load shared object '/home/brj/R/x86_64-pc-linux-gnu-library/3.6/00LOCK-soq/00new/soq/libs/soq.so':
  /home/brj/R/x86_64-pc-linux-gnu-library/3.6/00LOCK-soq/00new/soq/libs/soq.so: undefined symbol: _ZN4EchoC1EP7SEXPREC
Error: loading failed
Execution halted
ERROR: loading failed
我的问题是:我如何让两者都工作?
我在 R.3.6.3 和
R> sessionInfo()
....
other attached packages:
[1] inline_0.3.15 Rcpp_1.0.4.6 
....
附录
对于那些试图遵循上面的例子的人:源文件被准确命名是非常重要的 <package_name>_types.h .否则,自动生成的 RcppExports.cpp不会#include它,因此 Echo类不会在那里定义。这将导致编译错误。

最佳答案

错误消息提示声明但未定义 Echo(SEXP) , 这意味着扩展 Rcpp::as<> .对于由 Rcpp 模块处理的类,使用 RCPP_EXPOSED_* 更容易。宏:

 #include <Rcpp.h>

class Echo {
private:
    std::string message;
public:
    Echo(std::string message) : message(message) {}

    std::string get() { return message; }
};

RCPP_EXPOSED_AS(Echo);

using namespace Rcpp;

RCPP_MODULE(echo_module) {
    class_<Echo>("Echo")
    .constructor<std::string>()
    .method("get", &Echo::get)
    ;
};

// [[Rcpp::export]]
void shout(Echo e) {
    Rcout << e.get() << "!" << std::endl;
}

/***R
e <- new(Echo, "Hello World")
print(e$get())
shout(e)
*/ 

输出:

> Rcpp::sourceCpp('62228538.cpp')

> e <- new(Echo, "Hello World")

> print(e$get())
[1] "Hello World"

> shout(e)
Hello World!

所有这些都不是在一个包中,而是使用 Rcpp::sourceCpp .不过,我希望它也能在一个包中工作。

关于c++ - 混合 Rcpp 模块和 Rcpp::export,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62228538/

相关文章:

c++ - 声明全局变量,在方法中初始化

c++ - 如何将参数传递给已经开始运行的线程

r - 如何编织/编织到不同的文件名?

r - 为什么 nls(非线性最小二乘法)在 R 中不起作用

c++ - 提高 Rcpp 编译速度

c++ - 容器类型和编译时类型推导

c++ - 为什么 std::none_of 比手动循环更快?

r - 如何将 lapply 中的新值分配给列表中数据帧中的新列

r - 如何在 RcppArmadillo 中复制随机抽奖?

RcppArmadillo 传递用户定义函数