我有一个创建对象(类A的实例)的库,并将它们传递给应该能够调用其方法的python程序。将C++类实例传递给python并使用boost :: 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> >();
}
代码缺少其中蟒蛇得到existing_instance
的一部分。我没有粘贴,但我们只是说我为此使用了回调机制。
此代码的工作,但我有几个问题:
在计数功能(和所有其他C++操作函数)是精细传递
a
一样,或者最好是像做const shared_ptr<A>&
?在我在python boost文档中找到的代码片段中,经常使用该引用,但我不了解其中的差别(当然,除了具有较高的引用计数器外)。此代码是否“安全”?当我将existing_instance传递给python时,它的计数器会增加(只是一次,即使在python中,我也会创建更多的对象副本),所以没有办法让C++代码可以销毁对象,只要python成立至少一个“复制”。我对么?我试图玩弄指针,似乎我是正确的,我只是想确定一下。
我想阻止python创建实例A.他们应该只能从C++代码传递。我怎么能做到这一点? 编辑:发现,我只需要使用NO_INIT和不可复制:
class_<A, boost::noncopyable>("A", no_init)
什么之间的区别(实际上) “class_ (” A “NO_INIT)” 和“提升: :python :: class_ >(“A”,boost :: python :: no_init)“? 即使没有在“class_”之后指定“boost :: shared_ptr ”,我发布的代码仍然完美。那么,为什么我需要这个? – Emiliano 2010-08-01 16:27:33
它指定了实际上由python“A”包装的默认类型 - 所以如果你有一个C++函数返回一个'A','A *'shared_ptr或者类似的东西,并且暴露给python,那么返回值将被保存为shared_ptr - 如果您经常将这些对象传入或传出python,那么它将会被正确处理。 有关更多信息,请参见http://www.boost.org/doc/libs/1_43_0/libs/python/doc/v2/class.html#HeldType(尤其是第2点)。 – James 2010-08-01 17:32:46