2012-04-01 26 views
1

什么是SWIG等同于存储一个任意python对象的副本?SWIG相当于存储一个boost :: python :: object

我很确定我在问什么是可能的,因为它可以与boost :: python一起工作(见下文),但是我看不到使用SWIG来做到这一点的方法。

#include <boost/python.hpp> 

using namespace boost::python; 

class MyClass 
{ 
public: 
    // other operations 
    object get_info() { return info_; } 
    void set_info(object info) { info_ = info; } 

private: 
    object info_; 
}; 

BOOST_PYTHON_MODULE(mymodule) 
{ 
    class_<MyClass>("MyClass") 
     .def("get_info", &MyClass::get_info) 
     .def("set_info", &MyClass::set_info) 
    ; 
} 

回答

1

最简单的例子是:

%module test 

%inline %{ 
class MyClass 
{ 
public: 
    // other operations 
    PyObject *get_info() { return info_; } 
    void set_info(PyObject *info) { info_ = info; } 

private: 
    PyObject *info_; 
}; 
%} 

例如为:

 
swig -python -Wall -c++ test.i 
g++ -Wall -Wextra test_wrap.cxx -I/usr/include/python2.6 -o _test.so -shared 
python 
Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40) 
[GCC 4.4.5] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import test 
>>> foo = test.MyClass() 
>>> str = "hi" 
>>> foo.set_info(str) 
>>> print foo.get_info() 
hi 
>>> 

但请注意,在这种情况下,标的物的所有权没有发生变化。如果我完成了foo.set_info("hi"),那么它将被释放,因为在它被称为foo.get_info()的时候没有保留引用。

您可以修复,它通过添加调用:

Py_INCREF(info); 

set_info(),但随后你需要一个相应的DECREF在析构函数,或者如果set_info()当提及已持有被调用,或为复制建设或分配。 (或者一些很好的RAII类型可以为你做所有这些......)

+0

因此,如果这个类是不可复制的,那么一个简单的INCREF/DEFREF就足够了?我不必担心任何其他特殊情况? – 2012-04-02 00:06:28

+0

@AndrewWalker - 取决于你在想什么天真。如果你已经设置了一个集合,你需要DECREF。当你摧毁时你也需要DECREF。我真的建议去RAII的方法 - 很难让它错误。 – Flexo 2012-04-02 00:20:38