2015-10-23 84 views
4

我有一個叫做multicool的R包,用於處理multisets的排列。目前,在內部,存在一個C++類,並且調用initMC會創建一個類Multicool類的新對象,然後可以完成我需要的所有事情。但是,沒有簡單的方法來釋放分配給此對象的內存。這對於簡單的用途並不重要,但我有一個可能會調用這個數十萬次的應用程序。Rcpp導出的模塊沒有暴露

我認爲,解決方案是使用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) 

到我的空間文件

我的構造已添加

RcppModules: mcModule 

到我的描述文件

和我在.onLoad功能

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

這一切編譯和封裝建立毫無怨言加入loadRcppModules通話。但是,當我創建一個新的MULTICOOL對象,我得到上述錯誤

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

任何幫助或建議,將不勝感激

+0

你有沒有看到我的其他修改? –

+0

是的,謝謝@ dirk-eddelbuettel –

回答

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$Multicool前加入

mcModule <- new(mcModule) 

編輯:看起來你錯過了loadModule("mcModule", TRUE)調用。

編輯2:更明確,我從包中添加文件到(工作)testRcppModule並提出您所做的一個變化(至DESCRIPTION)和一個以上的R文件來加載模塊:

[email protected]:/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 
[email protected]:/tmp/rcpp/module$ 

就這樣,一切都很好:

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

Thanks @ dirk-eddelbuettel - 讓我更進一步,但仍然是一個錯誤: '> mcModule < - new(mcModule)' '.getClassFromCache(Class,where,resolve.msg = resolve.msg): object'mcModule'not found' –

+2

回過頭來看看單元測試示例包的文件集(https:// github。 com/RcppCore/Rcpp/tree/master/inst/unitTests/testRcppModule)(也是您安裝的一部分)並對其進行修改。我個人比較喜歡從頭開始。我還經常保持模塊名稱與類名相同,以免讓我自己在我需要的時候感到困惑...... –

+0

謝謝德克(@ dirk-eddelbuettel)。我也將它添加到testRccpModule項目中。如果我能看到我在做什麼不同,但我是該死的,但這不是我的問題! :-)謝謝 有一件值得注意的事情是**當**成功時,該類可用於R Studio中的製表符完成。一個愚蠢的成功指標,但很有用 –