Emi*_*ano 13 c++ python boost boost-python
我有一个库创建对象(类A的实例)并将它们传递给python程序,该程序应该能够调用它们的方法.
基本上我有C++类实例,我想从python中使用它们.有时,该对象应该传递回C++进行一些操作.
我创建了以下包装器文件(假设该New函数在C++代码中的某处调用):
#include <boost/python.hpp>
#include <iostream>
#include <boost/smart_ptr.hpp>
using namespace boost;
using namespace boost::python;
int calls = 0;
struct A
{
int f() { return calls++; }
~A() { std::cout << "destroyed\n"; }
};
shared_ptr<A> existing_instance;
void New() { existing_instance = shared_ptr<A>( new A() ); }
int Count( shared_ptr<A> a ) { return a.use_count(); }
BOOST_PYTHON_MODULE(libp)
{
class_<A>("A")
.def("f", &A::f)
;
def("Count", &Count);
register_ptr_to_python< shared_ptr<A> >();
}
Run Code Online (Sandbox Code Playgroud)
代码缺少python获取的部分existing_instance.我没有粘贴它,但我只是说我为此目的使用回调机制.
这段代码有效,但我有几个问题:
在Count函数(以及所有其他C++操作函数中)可以这样传递a或者更好地做类似的事情const shared_ptr<A>&吗?在我在python boost文档中找到的代码片段中经常使用引用,但我不理解其中的区别(当然,除了有更高的引用计数器).
这段代码"安全"吗?当我将existing_instance传递给python时,它的计数器将递增(只有一次,即使在python中我制作了更多的对象副本,当然)所以C++代码没有办法可以破坏对象,就像python一样至少是一个"副本".我对么?我试着用指针玩,看来我是对的,我只想确定一下.
我想阻止python创建A的实例.它们只能从C++代码传递.我怎么能实现这一目标?编辑:发现,我只需要使用no_init和noncopyable:class_<A, boost::noncopyable>("A", no_init)
Jam*_*mes 14
boost::python知道所有boost::shared_ptr,但你需要告诉它boost::shared_ptr<A>有一个实例A,你通过添加boost::shared_ptr<A>模板参数列表来做到这一点,class_关于这个'Held Type'的更多信息在boost文档中.
为了防止从python创建实例,你添加boost::python::no_init到class_构造函数,所以最终得到:
boost::python::class_< A, boost::shared_ptr<A> >("A", boost::python::no_init)
//... .def, etc
;
Run Code Online (Sandbox Code Playgroud)
在一般你不应该通过引用传递围绕共享指针,因为如果到共享指针引用无效,则引用到的共享指针指向也是无效的(因为服用共享指针的引用未增加指向对象的引用计数器).
将boost::shared_ptr对象传递给python和从python 传出是完全安全的,只要你不改变引用计数,引用计数(python和shared_ptr)就会被正确管理return_value_policy.如果你更改python中公开的方法的策略,以便它返回对共享指针的引用,那么你可能会导致问题,就像通过c ++引用传递共享指针可能会导致问题一样.
(另外,你应该make_shared<A>(...)优先使用shared_ptr<A>(new A(...)).)
| 归档时间: |
|
| 查看次数: |
5287 次 |
| 最近记录: |