如何将基本类型的共享_ptr导出到python

如何将基本类型的共享_ptr导出到python,python,c++,boost-python,Python,C++,Boost Python,我试图在python中使用基本类型(例如int或double)的共享_ptr,但我不知道如何将其导出到python: 我有以下课程: class Holder { public: Holder(int v) : value(new int(v)) {}; boost::shared_ptr<int> value; }; 发生了以下情况: TypeError: No to_python (by-value) converter found for C++ type:

我试图在python中使用基本类型(例如int或double)的共享_ptr,但我不知道如何将其导出到python:

我有以下课程:

class Holder
{
public:
    Holder(int v) : value(new int(v)) {};
    boost::shared_ptr<int> value;
};
发生了以下情况:

TypeError: No to_python (by-value) converter found for C++ type: class boost::shared_ptr<int>
<代码> Type错误:没有C++的TyPython(按值)转换器:类Booo::SyrdypTR
我的问题是:如何将
boost::shared_ptr
导出到python?

需要吗?Python有自己的引用计数 机制,使用它可能更简单。(但是很多 取决于C++上的内容。 否则:您可能需要定义一个Python对象来 包含共享指针。这相对简单: 定义如下:

struct PythonWrapper
{
    PyObject_HEAD
    boost::shared_ptr<int> value;
    //  Constructors and destructors can go here, to manage
    //  value.
};
struct PythonWrapper
{
皮尤头
boost::共享的ptr值;
//构造函数和析构函数可以在这里进行管理
//价值观。
};
并像对待任何其他对象一样声明和管理它;只是 确保在创建该类型的任何对象时执行
new
已创建(并且必须在您提供给的函数中创建) Python,如果
tp_new
字段中的函数中没有其他内容, 在您放入
tp_dealloc
字段的函数中添加一个
delete
您注册的对象类型。

可以使用与其他类型相同的方式将
boost::shared_ptr
导出到Python:

boost::python::class((…);
但是,在公开
shared\u ptr
时,请注意引入的语义。例如,考虑将一个代码>保持器。值< /代码>分配给另一个<代码>保持器。Value<代码>简单地调用<代码> Boo::SyrdYPPTR <代码>赋值操作符,和<代码>保持器。操作由
指向的
int
,而不是将
指向新的
int

h1 = Holder(10)
h2 = Holder(20)
h1.value = h2.value # h1.value and h2.value point to the same int.
h1.increment() # Change observed in h2.value.  The semantics may be unexpected
               # by Python developers.

下面是一个完整的示例,它基于原始代码公开了
boost::shared_ptr

#包括
#包括
#包括
#包括
阶级持有者
{
公众:
支架(int v)
:值(新整数(v))
{};
boost::共享的ptr值;
};
std::字符串持有者\u值\u str(const boost::共享\u ptr&value)
{
std::stringstream;
流导入示例
>>>h1=示例。支架(10)
>>>h2=示例。支架(20)
>>>打印h1.0值
0x25f4bd0包含10个
>>>打印h2.0值
0x253f220包含20个
>>>h1.value=h2.value
>>>打印h1.0值
0x253f220包含20个

可选地,如果考虑<代码> SyddYPPT/<代码>,只不过是C++内存管理代理,那么在Python中,将<代码>保持器>值<代码>暴露为合理的< <代码> INT/COM>,即使<代码>保持::值<代码>:是:SydDypPTR 。这将为Python开发人员提供预期的语义。并允许这样的语句

h1.value=h2.value+5
。下面的示例使用辅助函数将
Holder::value
转换为
int
,而不是公开
boost::shared_ptr
类型:

#包括
#包括
阶级持有者
{
公众:
支架(int v)
:值(新整数(v))
{};
boost::共享的ptr值;
};
///@用于获取Holder.value的简短辅助函数。
int get_holder_值(const holder&self)
{
返回*(自我价值);
}
///@用于设置Holder.value的简短辅助功能。
无效集合\u持有者\u值(持有者和自身,int值)
{
*(自我价值)=价值;
}
BOOST_PYTHON_模块(示例)
{
名称空间python=boost::python;
python::scope holder=python::class_(
“Holder”,python::init()
.添加_属性(“值”,
python::make_函数(&get_值),
python::make_函数(&设置_值))
;
}
互动使用:

>>导入示例
>>>h1=示例。支架(10)
>>>h2=示例。支架(20)
>>>断言(h1.value==10)
>>>断言(h2.value==20)
>>>h1.value=h2.value
>>>断言(h1.value==20)
>>>h1.1值+=22
>>>断言(h1.value==42)
>>>断言(h2.value==20)

您需要什么样的语义?继续上面的例子,您是否希望能够将整数值赋给
h1.value
,并将它们反映在
h2.value
中?类似这样的东西呢
x=h1.value;x=42
…应该
h2.value
以某种方式计算为
42
atement?您所问的有点违背Python的本质,但我们可能会找到一个合理的答案。
struct PythonWrapper
{
    PyObject_HEAD
    boost::shared_ptr<int> value;
    //  Constructors and destructors can go here, to manage
    //  value.
};
h1 = Holder(10)
h2 = Holder(20)
h1.value = h2.value # h1.value and h2.value point to the same int.
h1.increment() # Change observed in h2.value.  The semantics may be unexpected
               # by Python developers.