如何将基本类型的shared_ptr导出到python
How to export a shared_ptr of a fundamental type to python
我试图在python中使用基本类型的shared_ptr(例如int或double),但我不知道如何将其导出到python:
我有以下类:
class Holder
{
public:
Holder(int v) : value(new int(v)) {};
boost::shared_ptr<int> value;
};
类以这种方式被导出:
class_<Holder>("Holder", init<int>())
.def_readwrite("value", &Holder::value);
在python代码中,我试图使用已经存在的实例设置"holder instance .value"。
h1 = mk.Holder(10)
h2 = mk.Holder(20)
h1.value = h2.value
发生以下情况:
TypeError: No to_python (by-value) converter found for C++ type: class boost::shared_ptr<int>
我的问题是:我如何将boost::shared_ptr<int>
导出到python?
可以使用boost::python::class_
将boost::shared_ptr<int>
导出到Python,方法与其他类型相同:
boost::python::class_<boost::shared_ptr<int> >(...);
但是,在公开shared_ptr
时要小心引入的语义。例如,将一个Holder.value
赋值给另一个Holder.value
只是调用boost::shared_ptr<int>
的赋值操作符,并且Holder.increment()
操作value
所指向的int
,而不是让value
指向新的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>
的完整示例:
#include <sstream>
#include <string>
#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>
class Holder
{
public:
Holder(int v)
: value(new int(v))
{};
boost::shared_ptr<int> value;
};
std::string holder_value_str(const boost::shared_ptr<int>& value)
{
std::stringstream stream;
stream << value.get() << " contains " << *value;
return stream.str();
}
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
{
python::scope holder = python::class_<Holder>(
"Holder", python::init<int>())
.def_readwrite("value", &Holder::value)
;
// Holder.Value
python::class_<boost::shared_ptr<int> >("Value", python::no_init)
.def("__str__", &holder_value_str)
;
}
}
互动用法:>>> import example
>>> h1 = example.Holder(10)
>>> h2 = example.Holder(20)
>>> print h1.value
0x25f4bd0 contains 10
>>> print h2.value
0x253f220 contains 20
>>> h1.value = h2.value
>>> print h1.value
0x253f220 contains 20
或者,如果认为shared_ptr
只不过是一个c++内存管理代理,那么在Python中将Holder.value
公开为int
可能是合理的,即使Holder::value
是boost::shared_ptr<int>
。这将为Python开发人员提供预期的语义并允许诸如h1.value = h2.value + 5
之类的语句。下面是一个使用辅助函数将Holder::value
转换为int
,而不是暴露boost::shared_ptr<int>
类型的示例:
#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>
class Holder
{
public:
Holder(int v)
: value(new int(v))
{};
boost::shared_ptr<int> value;
};
/// @brief Auxiliary function used to get Holder.value.
int get_holder_value(const Holder& self)
{
return *(self.value);
}
/// @brief Auxiliary function used to set Holder.value.
void set_holder_value(Holder& self, int value)
{
*(self.value) = value;
}
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::scope holder = python::class_<Holder>(
"Holder", python::init<int>())
.add_property("value",
python::make_function(&get_holder_value),
python::make_function(&set_holder_value))
;
}
互动用法:>>> import example
>>> h1 = example.Holder(10)
>>> h2 = example.Holder(20)
>>> assert(h1.value == 10)
>>> assert(h2.value == 20)
>>> h1.value = h2.value
>>> assert(h1.value == 20)
>>> h1.value += 22
>>> assert(h1.value == 42)
>>> assert(h2.value == 20)
你需要吗?Python有自己的引用计数机理,用它可能会更简单。(但是很多取决于c++端发生了什么)
否则:您可能需要定义一个Python对象来包含共享指针。这是相对简单的:只需定义如下内容:
struct PythonWrapper
{
PyObject_HEAD
boost::shared_ptr<int> value;
// Constructors and destructors can go here, to manage
// value.
};
并像对待其他对象一样声明和管理它;只是当任何类型的对象都是时,请确保执行new
创建(并且必须在您提供给的函数中创建)Python中,如果tp_new
字段中的函数中没有其他内容,在tp_dealloc
字段中的函数中添加一个delete
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- Pybind11:将元组列表从Python传递到C++
- 如何在c++中使用引用实现类似python的行为
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 递归列出所有目录中的C++与Python与Ruby的性能
- IPC使用多个管道和分支进程来运行Python程序
- 从python中调用C++函数并获取返回值
- Python 3.7 和 excess_args 的 SWIG 问题
- Python中的for循环与C++有何不同
- 使用Pybind11向Python公开Eigen::张量
- CLANG 编译器 说:变量"PTR"可能未初始化
- Python str to C++ to Python str
- 如何使用Python从C++中读取谷物序列化数据
- 如何在C++中使用pybind11加载一个pickle python列表
- 如何在c++中使用system()来运行包含空格的python脚本
- python集合的C++等价物是什么.计数器
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 如果C++对象的类在另一个boost模块中声明,如何使用boost将指向该对象的指针返回到python
- 从python调用openMP共享库时,未定义opnMP函数
- Python OpenCV将mat-ptr传递给c++代码