2013-11-28 120 views
2

我正在使用Rcpp和模块将一些用C++编写的MCMC软件转换为R包。在这方面,我需要维护一个全局变量的指针,并指向某个类的最新对象。C++全局变量导致段错误

这里是在R-脚本的形式很简单的例子:

require(Rcpp) 
require(inline) 

inc <- ' 

using namespace Rcpp; 

class test; 
test* glob; //global pointer 


class test{ 
    private: 
    double foo; 
    public: 
    test(double foo_) : foo(foo_) { 
     glob=this; // the line causes segfault 
    }; 
    double get_foo(){return foo;}; 
}; 

RCPP_MODULE(test){ 
    class_<test>("test") 
    .constructor<double>() 
    .property("foo",&test::get_foo) 
    ; 

} 

' 

fx <- cxxfunction(signature(),plugin="Rcpp",include=inc); 
test_module <- Module("test",getDynLib(fx)) 
test <- test_module$test 
t1 <- new(test,1.0) 

我试图让在是类似以下内容(C++):

#include<iostream> 

class test; 
test* glob; 


class test{ 
    private: 
    double foo; 
    public: 
    test(double foo_) : foo(foo_) {glob=this;}; 
    double get_foo(){return foo;}; 
}; 

int main(){ 
    test t1(1.0); 
    test t2(2.0); 
    std::cout << (*glob).get_foo() << std::endl; 
} 

它编译和运行,因为它应该。

由于提前, 问候,撕毁Kleppe

+0

添加R标签以及... –

回答

2

这似乎是两个不相关的和简单的错误。

首先,您需要制作指针static。事情然后工作。

其次,使用Rcpp模块与inline是不是 更长的最简单的方法,我们通常建议使用一个包或Rcpp属性,如下所示。

正确的代码,其中包括显式消息传送到stdout在构造:

#include <Rcpp.h> 

using namespace Rcpp; 

class test; 
static test* glob = NULL; //global pointer 


class test{ 
    private: 
    double foo; 
    public: 
    test(double foo_) : foo(foo_) { 
     Rcpp::Rcout << "Seeing foo_ of " << foo_ << " in ctor\n"; 
     glob=this; // the line causes segfault 
    }; 
    double get_foo(){return foo;}; 
}; 

RCPP_MODULE(test){ 
    class_<test>("test") 
    .constructor<double>() 
    .property("foo",&test::get_foo) 
    ; 
} 

然后简单使用从命令行(使用利特勒; R或RSCRIPT是等同的):

$ r -lRcpp -e 'sourceCpp("/tmp/tore.cpp"); tt <- new(test, 1.23); print(tt$foo)' 
Seeing foo_ of 1.23 in ctor 
[1] 1.23 
$ 

注我们如何跳过所有的模块实例化等。

+0

Dirk;非常感谢!这节省了我的一天。问候 - 去 – user3045925

+0

没有汗水。如同这里的习惯一样,您可以随意选择“接受”答案(只要您点击勾号标记,就可以看到您的答案),并/或点击向上箭头向上移动答案。这就是网站的推出方式。顺便说一下,我已经提出了你的问题。 –