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

Posted

技术标签:

【中文标题】在 SWIG 中携带自定义 Python 数据的 C++ 对象【英文标题】:C++ Objects That Carry Custom Python Data In SWIG 【发布时间】:2011-04-05 02:00:03 【问题描述】:

有没有办法让 SWIG 包装的 C++ 对象在 C++ 和 Python 之间来回传递时携带自定义 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 的_getattr_ 函数,那么也许可以从内部 PyObject* 存储和加载未知属性(通过自动拥有 SWIG 子类 MyClass,或者通过拥有这样的对象已存在于 MyClass 中)?

谢谢!

【问题讨论】:

【参考方案1】:

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

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,而不是现有值,我找不到访问类型图中现有值的官方方法。以上取决于 SWIG 将对象 (MyClass *) 命名为 arg1。有效,但可能无法在未来的 SWIG 版本中移植。

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

3) 它要求类有一个data 成员。这可以满足我当前的需求,并且可以由基类处理。

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

【讨论】:

以上是关于在 SWIG 中携带自定义 Python 数据的 C++ 对象的主要内容,如果未能解决你的问题,请参考以下文章

如何使用静态变量和自定义 getter 和 setter 在 SWIG 中扩展结构?

在 Python 中使用自定义 Qt 子类

SWIG 和 Python3 导入错误

k3 bom自定义字段如何自动携带到计划订单中

Python:SWIG:包装对结构的访问

Python 错误:在 SWIG 生成的 C++ 模板代码模块中未定义构造函数