在SWIG中携带自定义Python数据的C ++对象

时间:2011-04-05 02:00:04

标签: c++ python attributes swig

有没有办法让SWIG包装的C ++对象随身携带自定义Python数据,因为它们在C ++和Python之间来回传递?例如:

example.h文件

class MyClass
{
public:
    int foo;
};

// Black box functions.
// Only thing guaranteed is that the last object handed to consume
// will be returned by eject.
void consume(MyClass *obj);
MyClass *eject();

example.i

%module Example

%{
        #include "example.h"
%}

%include "example.h"

test.py

import Example

a = Example.MyClass()
a.bar = "Puppies"

Example.consume(a)
b = Example.eject()

## Should output "Puppies"
print b.bar

当前输出是“AttributeError:bar”。

有没有获得这种功能?如果可以自定义MyClass的SWIG's_ getattr _函数,那么也许可以从内部PyObject *存储和加载未知属性(通过自动拥有SWIG子类MyClass,或者通过具有这样的对象已经存在于MyClass中)?

谢谢!

1 个答案:

答案 0 :(得分:0)

这是迄今为止我提出的唯一(部分)解决方案:

class MyClass
{
...
MyClass() : data(NULL) {}
~MyClass() {if(data) Py_DECREF(data);}
PyObject *data;
};


%typemap(in) PyObject* data {
    if(arg1 && arg1->data != NULL)
        Py_DECREF(arg1->data);
    $1 = $input;
    Py_XINCREF($1);
}

%typemap(out) PyObject* data {
    $result = $1;
}

<强>问题

1)SWIG将$1设置为NULL,而不是现有值,我找不到以正式方式访问typemap中的现有值。以上内容取决于SWIG将对象(MyClass *)命名为arg1。可行,但可能无法在未来的SWIG版本中移植。

2)Python代码必须是a.data.bar = "Puppies"。这没关系,但并不完美。

3)要求班级有data成员。这对我目前的需求是可以的,可以由基类处理。

4)类的析构函数还必须知道数据并清理它。再次,可以满足我目前的需求,但有些麻烦。