2017-08-11 123 views
0

怪異訪問我做了一個小再現的例子:與外部指針

#include <Rcpp.h> 
using namespace Rcpp; 

class Index { 
public: 
    Index(int i_) : i(i_) {} 
    int getI() { return i; } 
private: 
    int i; 
}; 

// [[Rcpp::export]] 
SEXP getXPtrIndex(int i) { 
    Rcout << "getXPtrIndex: i = " << i << std::endl; 
    Index ind(i); 
    Rcout << "getXPtrIndex: ind.i = " << ind.getI() << std::endl; 
    return XPtr<Index>(&ind, true); 
} 

// [[Rcpp::export]] 
void getXPtrIndexValue(SEXP ptr) { 
    XPtr<Index> ind_ptr(ptr); 
    Rcout << "getXPtrIndexValue: ind_ptr->i = " << ind_ptr->getI() << std::endl; 
    Index ind = *ind_ptr; 
    Rcout << "getXPtrIndexValue: ind.i = " << ind.getI() << std::endl; 
} 

基本上,我定義了一個小的類,用函數來獲得這個類的一個元件的外部指針沿。將類元素返回給C++時,最後一個函數用於打印奇怪的訪問器。

結果R:

> (extptr <- getXPtrIndex(10)) 
getXPtrIndex: i = 10 
getXPtrIndex: ind.i = 10 
<pointer: 0x7ffeeec31b00> 

> getXPtrIndexValue(extptr) 
getXPtrIndexValue: ind_ptr->i = 33696400 
getXPtrIndexValue: ind.i = 0 

爲什麼我不能訪問10

我正在使用Rcpp版本0.12.12(最新的我認爲)。

回答

3

它似乎與臨時對象有關---當第二個函數運行時,第一個函數的「內容」已經消失。

所以,要麼只是做

Index ind(10); 

一個全球性的,並註釋掉在你的第一個功能就行了。那麼一切都桃色(我稍微改變將R調用):

R> extptr <- getXPtrIndex(10) 
getXPtrIndex: i = 10 
getXPtrIndex: ind.i = 10 

R> getXPtrIndexValue(extptr) 
getXPtrIndexValue: ind_ptr->i = 10 
getXPtrIndexValue: ind.i = 10 
R> 

或者,它也以同樣的方式,當你讓你Index反對static,以確保持久性。下面更正了示例。

#include <Rcpp.h> 
using namespace Rcpp; 

class Index { 
public: 
    Index(int i_) : i(i_) {} 
    int getI() { return i; } 
private: 
    int i; 
}; 

// [[Rcpp::export]] 
SEXP getXPtrIndex(int i) { 
    Rcout << "getXPtrIndex: i = " << i << std::endl; 
    static Index ind(i); 
    Rcout << "getXPtrIndex: ind.i = " << ind.getI() << std::endl; 
    return XPtr<Index>(&ind, true); 
} 

// [[Rcpp::export]] 
void getXPtrIndexValue(SEXP ptr) { 
    XPtr<Index> ind_ptr(ptr); 
    Rcout << "getXPtrIndexValue: ind_ptr->i = " << ind_ptr->getI() << std::endl; 
    Index ind = *ind_ptr; 
    Rcout << "getXPtrIndexValue: ind.i = " << ind.getI() << std::endl; 
} 

/*** R 
extptr <- getXPtrIndex(10) 
getXPtrIndexValue(extptr) 
*/ 
+0

好的我不確定我是否理解。我認爲XPtr正在保護C++對象不被破壞。同樣使用'Rcpp :: XPtr ptr(new Index(i),true);'似乎工作。好嗎? –

+0

是的,因爲它實際分配。你之前擁有的是由C++範圍管理,一旦功能消失,它就會消失。 –

+0

我會用我的解決方案,但我驗證你的解釋。謝謝。 –