RCPP导出模块未暴露

Jam*_*ran 5 c++ module r rcpp

我有一个名为multicool的R包,它可以处理多集的排列。当前,在内部,存在一个C ++类,对initMC的调用将创建一个类Multicool的新对象,该对象可以完成我需要它执行的所有操作。但是,没有简单的方法来释放分配给该对象的内存。对于简单的使用来说并不重要,但是我有一个应用程序可能会调用数十万次。

我认为解决方案是使用Rcpp模块将类公开给R。但是,我尝试按照说明进行操作,但出现错误:

错误:找不到对象“ mcModule”

最初-我只想公开该对象及其构造函数。这是我的班级定义

#include <Rcpp.h>

using namespace Rcpp;
using namespace std;

class Multicool{
  struct list_el {
    int v;
    struct list_el * n;
  };
  typedef struct list_el item;

  item *h;
  item *t;
  item *i;

  int *m_pnInitialState; 
  int *m_pnCurrState;
  int m_nLength;
  bool m_bFirst;

  public:
   // constructor
  Multicool(IntegerVector x){
    int nx = (int)x.size();
  }
};
Run Code Online (Sandbox Code Playgroud)

然后我导出类和构造函数

RCPP_MODULE(mcModule){
  using namespace Rcpp;

  class_<Multicool>("Multicool")

  .constructor<IntegerVector>()
  ;
}
Run Code Online (Sandbox Code Playgroud)

我加了线

import(Rcpp)
Run Code Online (Sandbox Code Playgroud)

到我的NAMESPACE文件

我已经添加了

RcppModules: mcModule
Run Code Online (Sandbox Code Playgroud)

到我的DESCRIPTION文件

并且我在.onLoad函数中添加了对loadRcppModules的调用

.onLoad <- function(libname, pkgname) {
  loadRcppModules()
}
Run Code Online (Sandbox Code Playgroud)

所有这些都可以编译,并且程序包的构建没有任何抱怨。但是当我创建一个新的Multicool对象时,出现了上述错误

> library(multicool)
> Multicool = mcModule$Multicool
Error: object 'mcModule' not found
Run Code Online (Sandbox Code Playgroud)

任何帮助或建议,将不胜感激

Dir*_*tel 4

通常您需要new先打电话。在我的RcppRedis包中看到:

RCPP_MODULE(Redis) {
    Rcpp::class_<Redis>("Redis")   

        .constructor("default constructor")  
        [...stuff omitted for brevity...]

    ;
}
Run Code Online (Sandbox Code Playgroud)

R 代码(例如在demo/目录中)的位置

suppressMessages(library(RcppRedis))

redis <- new(Redis)
Run Code Online (Sandbox Code Playgroud)

之后您可以访问redis$foo()属于模块一部分的函数等。

所以尝试添加

mcModule <- new(mcModule)
Run Code Online (Sandbox Code Playgroud)

在访问之前mcModule$Multicool

编辑:看来您错过了loadModule("mcModule", TRUE)电话。

编辑2:更明确地说,我将您的文件添加到testRcppModule包中的(工作)中,并对您所做的一项更改(对)进行了一项更改DESCRIPTION,并对 R 文件进行了另一项更改以加载模块:

edd@max:/tmp/rcpp/module$ diff -ru ~/git/rcpp/inst/unitTests/testRcppModule/  testRcppModule/ 
diff -ru /home/edd/git/rcpp/inst/unitTests/testRcppModule/DESCRIPTION testRcppModule/DESCRIPTION
--- /home/edd/git/rcpp/inst/unitTests/testRcppModule/DESCRIPTION        2015-08-26 15:53:03.891830292 -0500
+++ testRcppModule/DESCRIPTION  2015-10-22 21:34:23.716959638 -0500
@@ -10,6 +10,6 @@
 LazyLoad: yes
 Depends: methods, Rcpp (>= 0.8.5)
 LinkingTo: Rcpp
-RcppModules: RcppModuleWorld, stdVector, NumEx
+RcppModules: RcppModuleWorld, stdVector, NumEx, mcModule
 Packaged: 2010-09-09 18:42:28 UTC; jmc

diff -ru /home/edd/git/rcpp/inst/unitTests/testRcppModule/R/zzz.R testRcppModule/R/zzz.R
--- /home/edd/git/rcpp/inst/unitTests/testRcppModule/R/zzz.R    2015-08-26 15:53:03.891830292 -0500
+++ testRcppModule/R/zzz.R      2015-10-22 21:41:41.468532838 -0500
@@ -8,4 +8,5 @@
 loadModule("RcppModuleNumEx", TRUE)
 loadModule("RcppModuleWorld", TRUE)
 loadModule("stdVector", TRUE)
+loadModule("mcModule", TRUE)

Only in testRcppModule/src: multicool.cpp
edd@max:/tmp/rcpp/module$ 
Run Code Online (Sandbox Code Playgroud)

这样,一切都很好:

$ r --package testRcppModule --eval 'm <- new(mcModule); print(m)'
C++ object <0x757d18> of class 'mcModule' <0x1adeab0>
$ 
Run Code Online (Sandbox Code Playgroud)

  • 退后一步,查看(已交付、已尝试、已测试)[单元测试示例包的一组文件](https://github.com/RcppCore/Rcpp/tree/master/inst/unitTests/testRcppModule )(这也是您安装的一部分)并修改它。我个人更喜欢从头开始。我也经常保持模块名称等于类名称,以免自己混淆我需要的...... (2认同)
  • Dirk (@dirk-eddelbuettel) 我发现它需要两件事。首先按照您的建议使用“loadModule()”,但请原谅我,但我在小插图中找不到它,它还需要在 NAMESPACE 文件中显式导出模块,即“export(Multicool)”我想要询问 `loadModule(Multicool, TRUE)` 和使用我上面给出的 `.onload` 函数定义之间的区别。我认为这应该从描述文件中的“RcppModules”行中获取模块列表并加载它们? (2认同)
  • “NAMESPACE”是一个转移注意力的话题。这是一个 _R 侧_ 更改(即与 Rcpp 模块正交),需要列出所有要访问的符号。此外,这是自小插图编写以来所做的 R 更改,当然在我向您指出的工作示例中已解决,并且我也在四天前为您设置了该更改。 (2认同)