Search code examples
pythonc++inheritanceswigownership

SWIG C++/Python: inheritance proxy objects


I have something like that in C++ files, that compose my SWIG module :

class CObject {
    public:
        void do() {
            // some treatments
        }
};
class Interface {
    public:
        void add(CObject* obj) {
            obj->do();
        }
};

In python code, that used my SWIG module, there is something like that :

from mySwigModule import Interface, CObject

class MyObj(CObject):
    def __init__(self):
        super(CObject, self).__init__()


inter = Interface()
inter.add(MyObj()) // ERROR

This code is very basic. The real one deals with larger objects. But the problem is: when running Python code, something like that is printed :

NotImplementedError: Wrong number or type of arguments for overloaded function 'Interface_add'.
Possible C/C++ prototypes are:
    Interface::add(CObject *)

How can i explain to SWIG how cast the object in CObject ?

There is certainly something to do with typemaps, but i don't know exactly what. I tried to add this in interface file, without success :

 %typemap(in) CObject * {
     if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor)) == -1) {
         $1 = (CObject *) $1;
      }
 }

The error returned at compilation is something like :

 error: macro "SWIG_ConvertPtr" requires 4 arguments, but only 3 given
 In function ‘PyObject* _wrap_Interface_add__SWIG_0(PyObject*, PyObject*)’:
 error: ‘SWIG_ConvertPtr’ was not declared in this scope

In real code, Interface::add() is called with 2 arguments. Maybe typemaps need to specify types of others parameters ?

debian, python 3.2, SWIG 2.

EDIT: the real error is show.


Solution

  • Your __init__ has an error. Try this:

    def __init__(self):
        super(MyObj, self).__init__()
    

    or even this:

    def __init__(self):
        super().__init__()
    

    Complete test:

    /* example.i */
    %module example
    %inline %{
    class CObject { public: void do_it() {} };
    class Interface { public: void add(CObject* obj) {obj->do_it();} };
    %}
    
    # test.py
    from example import Interface, CObject
    
    class MyObj(CObject):
        def __init__(self): super(MyObj, self).__init__()
    
    Interface().add(MyObj())
    
    $ # build and test procedure
    $ swig -o example_wrap.cc -python -c++ example.i
    $ g++ -o example_wrap.os -c -fPIC -I/usr/include/python3.4 example_wrap.cc
    $ g++ -o _example.so -shared example_wrap.os
    $ python3 test.py 
    $