开发者

C++ Objects That Carry Custom Python Data In SWIG

开发者 https://www.devze.com 2023-02-21 21:17 出处:网络
Is there a way for C++ objects, wrapped by SWIG, to carry custom Python data with them as they pass back and forth between C++ and Python? Example:

Is there a way for C++ objects, wrapped by SWIG, to carry custom Python data with them as they pass back and forth between C++ and Python? Example:

example.h

class MyClass
{
public:
    int foo;
};

// Black box functions.
// Only thing guaranteed is that开发者_JAVA百科 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

The current output is an "AttributeError: bar".

Is there anyway to get this kind of functionality? If SWIG's_getattr_ functions for MyClass could be customized, then perhaps unknown attributes could be stored and loaded from an internal PyObject* (either by having SWIG sub-class MyClass automatically, or by having such an object already present in MyClass)?

Thank you!


This is the only (partial) solution I've come up with so far:

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;
}

Problems:

1) SWIG sets $1 to NULL, instead of the existing value, and I could not find an official way to access the existing value inside a typemap. The above depends on SWIG naming the object (MyClass *) as arg1. Works, but probably not portable across future SWIG versions.

2) The Python code must be a.data.bar = "Puppies". This is okay, but not perfect.

3) It requires that the class have a data member. This is okay for my current needs and can be handled by a base class.

4) The class's destructor must also be aware of data, and clean it up. Again, okay for my current needs, but somewhat cumbersome.

0

精彩评论

暂无评论...
验证码 换一张
取 消