我正在尝试使用Rcpp为C++脚本编写R绑定。其中一个函数需要std::shared_ptr object
。我发现很难初始化std::shared_ptr
obj并将其作为Rcpp::XPtr
对象返回到R端。
我试过(最小的例子):
#include <iostream>
#include <memory>
#include <Rcpp.h>
using namespace Rcpp;
using std::cout;
class TestClass {
public:
int value;
TestClass(int initial_val) {
value = initial_val;
};
};
//[[Rcpp::export]]
SEXP get_test_obj() {
Rcpp::XPtr<std::shared_ptr<TestClass>> ptr(std::make_shared<TestClass>(5), true);
return ptr;
};
但得到以下错误:
no matching function for call to 'Rcpp::XPtr<std::shared_ptr<TestClass> >::XPtr(std::shared_ptr<TestClass>, bool)'
有什么办法吗?还是我做错了
4条答案
按热度按时间hujrc8aj1#
来自@d3coy的答案几乎包含了所有的信息。
Rcpp::XPtr
是一个模板智能指针类,它的参数是被指针类,而不是它指向的类。因此,Rcpp::XPtr<std::shared_ptr<TestClass>>
将是指向std::shared_ptr<TestClass>*
的智能指针。注意*
,这是重要的一点。当
shared_ptr
超出作用域时,如果它是原始指针的最后一个保持器,那么原始指针可能会被删除。这绝对不是你想要的相反,您可以使用
new
创建一个原始指针,并将其馈送给XPtr
。当垃圾收集器通过XPtr
收集R对象时,这个指针将得到delete
d,这是你在处理外部指针时通常想要的。我知道目前的指导方针是尽可能多地使用
make_unique
和make_shared
而不是new
,但在这种情况下,您需要new
。聪明来自XPtr
,如果你把它和shared_ptr
混合在一起,它们会互相妨碍。8cdiaqws2#
我怀疑R端是否希望传递一个std::shared_ptr。我假设源代码中的其他代码依赖于std::shared_ptr,但您希望将内部原始指针传递给R。我还假设std::shared_ptr的生存期在您的代码中得到更适当的管理,因为所呈现的代码会使std::shared_ptr在函数之后超出范围,并在下一次解引用时崩溃。
在任何情况下,如果你只想把内部的原始指针传递给R,你会这样做(人为的):
piah890a3#
感谢所有的提示和“指针”。不知道这是否是正确的回应方式,但我想我会输入我找到的解决方案。
关键是R端确实不一定需要
std::shared_ptr
。然而,我正在与现有的C库接口。我需要示例化库的std::shared_ptr<TestClass>
(使用R)并反馈到C算法中,该算法需要std::shared_ptr<TestClass>
。我解决它的方法如下(示例和未测试):
在R中,我可以做:
mzmfm0qo4#
只是为了补充这个主题(我花了几天的时间,因为我是一个C++新手),下面的代码是基于Bart上面的解决方案,测试和确认。如果有一天有人有更简单的解决方案,请让我知道!
PS:Dirk的资源是了不起的(感谢您的所有工作),但我没有设法找到任何基于Rcpp的软件包处理这个问题=/