首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >混合Rcpp模块和Rcpp::导出

混合Rcpp模块和Rcpp::导出
EN

Stack Overflow用户
提问于 2020-06-06 07:12:24
回答 1查看 178关注 0票数 4

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

代码语言:javascript
复制
Rscript -e 'Rcpp::Rcpp.package.skeleton("soq")'

并将以下代码放入soq_types.h

代码语言:javascript
复制
#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;
}

注意,最后一个注释有额外的斜杠,不会导致函数被导出。当我现在跑步时:

代码语言:javascript
复制
$> 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()并重新安装我得到:

代码语言:javascript
复制
** 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和

代码语言:javascript
复制
R> sessionInfo()
....
other attached packages:
[1] inline_0.3.15 Rcpp_1.0.4.6 
....

附录

对于那些试图遵循上面的例子的人来说,非常重要的是源文件的名字应该是<package_name>_types.h。否则,自动生成的RcppExports.cpp将不会#include它,因此不会在那里定义Echo类。这将导致编译错误。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-06 19:07:13

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

代码语言:javascript
复制
 #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)
*/ 

输出:

代码语言:javascript
复制
> Rcpp::sourceCpp('62228538.cpp')

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

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

> shout(e)
Hello World!

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

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62228538

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档