【问题标题】:SWIG equivalent of storing a boost::python::object相当于存储 boost::python::object 的 SWIG
【发布时间】:2012-04-01 23:41:53
【问题描述】:

什么是 SWIG 等效于存储任意 python 对象的副本?

我很确定我的要求是可能的,因为它可以与 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 )
    ;
}

【问题讨论】:

    标签: c++ python swig boost-python


    【解决方案1】:

    最简单的例子是:

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

    例如:

    痛饮 -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,2010 年 12 月 27 日,00:02:40) [GCC 4.4.5] 在 linux2 上 输入“帮助”、“版权”、“信用”或“许可”以获取更多信息。 >>> 导入测试 >>> foo = test.MyClass() >>> str =“嗨” >>> foo.set_info(str) >>> 打印 foo.get_info() 你好 >>>

    但请注意,在这种情况下,对象的所有权并未更改。如果我改为使用foo.set_info("hi"),那么它将被释放,因为在它调用foo.get_info() 时没有保留任何引用。

    您可以通过添加调用来解决此问题:

    Py_INCREF(info);
    

    set_info() 中,但是您需要在析构函数中使用相应的DECREF,或者如果在已经持有引用时调用set_info(),或者用于复制构造或赋值。 (或者一些不错的 RAII 类型来为你做所有这些......)

    【讨论】:

    • 如果类是不可复制的,一个简单的 INCREF/DEFREF 就足够了吗?我不必担心任何其他特殊情况?
    • @AndrewWalker - 取决于你的想法有多天真。如果你调用 set 时已经设置了一个,你需要 DECREF。当您销毁时,您还需要 DECREF。我真的建议采用 RAII 方法 - 更难出错。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-10
    • 1970-01-01
    相关资源
    最近更新 更多