Rcpp导出的模块没有暴露

时间:2015-10-23 02:04:02

标签: c++ r module 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();
  }
};

然后我用

导出类和构造函数
RCPP_MODULE(mcModule){
  using namespace Rcpp;

  class_<Multicool>("Multicool")

  .constructor<IntegerVector>()
  ;
}

我添加了一行

import(Rcpp)

到我的NAMESPACE文件

我添加了

RcppModules: mcModule

到我的描述文件

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

.onLoad <- function(libname, pkgname) {
  loadRcppModules()
}

所有这些编译并且包构建没有抱怨。但是当我创建一个新的Multicool对象时,我得到了上述错误

> library(multicool)
> Multicool = mcModule$Multicool
Error: object 'mcModule' not found

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

1 个答案:

答案 0 :(得分:3)

您通常需要先new来电。请参阅我的RcppRedis包:

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

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

    ;
}

其中R代码(例如在demo/目录中)

suppressMessages(library(RcppRedis))

redis <- new(Redis)

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

所以尝试添加

mcModule <- new(mcModule)

访问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$ 

有了这一切,一切都很好:

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