Bipedal-locomotion-framework: Implement the machinery for the generation of the Python bindings

Created on 19 Oct 2020  Â·  17Comments  Â·  Source: dic-iit/bipedal-locomotion-framework

In this issue, we will track the problems related to the generation of the python bindings

All 17 comments

Today I tried to play with SWIG for the generation of the python bindings.
I tried to adapt the code of

I wrote the BipedalLocomotionFramework.i file
https://github.com/dic-iit/bipedal-locomotion-framework/blob/b76c17ff50090012840e6231276ebdc60f580b26/bindings/BipedalLocomotionFramework.i#L1

I've also introduced the the eigen.i and numpy.i files here

When I tried to generate the bindings I didn't get any error, however the BipedalLocomotion.py does not contains any class of the framework.

Click here to check the content of BipedalLocomotion.py

# This file was automatically generated by SWIG (http://www.swig.org).
# Version 3.0.12
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.

from sys import version_info as _swig_python_version_info
if _swig_python_version_info >= (2, 7, 0):
    def swig_import_helper():
        import importlib
        pkg = __name__.rpartition('.')[0]
        mname = '.'.join((pkg, '_BipedalLocomotion')).lstrip('.')
        try:
            return importlib.import_module(mname)
        except ImportError:
            return importlib.import_module('_BipedalLocomotion')
    _BipedalLocomotion = swig_import_helper()
    del swig_import_helper
elif _swig_python_version_info >= (2, 6, 0):
    def swig_import_helper():
        from os.path import dirname
        import imp
        fp = None
        try:
            fp, pathname, description = imp.find_module('_BipedalLocomotion', [dirname(__file__)])
        except ImportError:
            import _BipedalLocomotion
            return _BipedalLocomotion
        try:
            _mod = imp.load_module('_BipedalLocomotion', fp, pathname, description)
        finally:
            if fp is not None:
                fp.close()
        return _mod
    _BipedalLocomotion = swig_import_helper()
    del swig_import_helper
else:
    import _BipedalLocomotion
del _swig_python_version_info

try:
    _swig_property = property
except NameError:
    pass  # Python < 2.2 doesn't have 'property'.

try:
    import builtins as __builtin__
except ImportError:
    import __builtin__

def _swig_setattr_nondynamic(self, class_type, name, value, static=1):
    if (name == "thisown"):
        return self.this.own(value)
    if (name == "this"):
        if type(value).__name__ == 'SwigPyObject':
            self.__dict__[name] = value
            return
    method = class_type.__swig_setmethods__.get(name, None)
    if method:
        return method(self, value)
    if (not static):
        if _newclass:
            object.__setattr__(self, name, value)
        else:
            self.__dict__[name] = value
    else:
        raise AttributeError("You cannot add attributes to %s" % self)


def _swig_setattr(self, class_type, name, value):
    return _swig_setattr_nondynamic(self, class_type, name, value, 0)


def _swig_getattr(self, class_type, name):
    if (name == "thisown"):
        return self.this.own()
    method = class_type.__swig_getmethods__.get(name, None)
    if method:
        return method(self)
    raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name))


def _swig_repr(self):
    try:
        strthis = "proxy of " + self.this.__repr__()
    except __builtin__.Exception:
        strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)

try:
    _object = object
    _newclass = 1
except __builtin__.Exception:
    class _object:
        pass
    _newclass = 0

class SwigPyIterator(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, SwigPyIterator, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, SwigPyIterator, name)

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _BipedalLocomotion.delete_SwigPyIterator
    __del__ = lambda self: None

    def value(self):
        return _BipedalLocomotion.SwigPyIterator_value(self)

    def incr(self, n=1):
        return _BipedalLocomotion.SwigPyIterator_incr(self, n)

    def decr(self, n=1):
        return _BipedalLocomotion.SwigPyIterator_decr(self, n)

    def distance(self, x):
        return _BipedalLocomotion.SwigPyIterator_distance(self, x)

    def equal(self, x):
        return _BipedalLocomotion.SwigPyIterator_equal(self, x)

    def copy(self):
        return _BipedalLocomotion.SwigPyIterator_copy(self)

    def next(self):
        return _BipedalLocomotion.SwigPyIterator_next(self)

    def __next__(self):
        return _BipedalLocomotion.SwigPyIterator___next__(self)

    def previous(self):
        return _BipedalLocomotion.SwigPyIterator_previous(self)

    def advance(self, n):
        return _BipedalLocomotion.SwigPyIterator_advance(self, n)

    def __eq__(self, x):
        return _BipedalLocomotion.SwigPyIterator___eq__(self, x)

    def __ne__(self, x):
        return _BipedalLocomotion.SwigPyIterator___ne__(self, x)

    def __iadd__(self, n):
        return _BipedalLocomotion.SwigPyIterator___iadd__(self, n)

    def __isub__(self, n):
        return _BipedalLocomotion.SwigPyIterator___isub__(self, n)

    def __add__(self, n):
        return _BipedalLocomotion.SwigPyIterator___add__(self, n)

    def __sub__(self, *args):
        return _BipedalLocomotion.SwigPyIterator___sub__(self, *args)
    def __iter__(self):
        return self
SwigPyIterator_swigregister = _BipedalLocomotion.SwigPyIterator_swigregister
SwigPyIterator_swigregister(SwigPyIterator)

class StringVector(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, StringVector, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, StringVector, name)
    __repr__ = _swig_repr

    def iterator(self):
        return _BipedalLocomotion.StringVector_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _BipedalLocomotion.StringVector___nonzero__(self)

    def __bool__(self):
        return _BipedalLocomotion.StringVector___bool__(self)

    def __len__(self):
        return _BipedalLocomotion.StringVector___len__(self)

    def __getslice__(self, i, j):
        return _BipedalLocomotion.StringVector___getslice__(self, i, j)

    def __setslice__(self, *args):
        return _BipedalLocomotion.StringVector___setslice__(self, *args)

    def __delslice__(self, i, j):
        return _BipedalLocomotion.StringVector___delslice__(self, i, j)

    def __delitem__(self, *args):
        return _BipedalLocomotion.StringVector___delitem__(self, *args)

    def __getitem__(self, *args):
        return _BipedalLocomotion.StringVector___getitem__(self, *args)

    def __setitem__(self, *args):
        return _BipedalLocomotion.StringVector___setitem__(self, *args)

    def pop(self):
        return _BipedalLocomotion.StringVector_pop(self)

    def append(self, x):
        return _BipedalLocomotion.StringVector_append(self, x)

    def empty(self):
        return _BipedalLocomotion.StringVector_empty(self)

    def size(self):
        return _BipedalLocomotion.StringVector_size(self)

    def swap(self, v):
        return _BipedalLocomotion.StringVector_swap(self, v)

    def begin(self):
        return _BipedalLocomotion.StringVector_begin(self)

    def end(self):
        return _BipedalLocomotion.StringVector_end(self)

    def rbegin(self):
        return _BipedalLocomotion.StringVector_rbegin(self)

    def rend(self):
        return _BipedalLocomotion.StringVector_rend(self)

    def clear(self):
        return _BipedalLocomotion.StringVector_clear(self)

    def get_allocator(self):
        return _BipedalLocomotion.StringVector_get_allocator(self)

    def pop_back(self):
        return _BipedalLocomotion.StringVector_pop_back(self)

    def erase(self, *args):
        return _BipedalLocomotion.StringVector_erase(self, *args)

    def __init__(self, *args):
        this = _BipedalLocomotion.new_StringVector(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

    def push_back(self, x):
        return _BipedalLocomotion.StringVector_push_back(self, x)

    def front(self):
        return _BipedalLocomotion.StringVector_front(self)

    def back(self):
        return _BipedalLocomotion.StringVector_back(self)

    def assign(self, n, x):
        return _BipedalLocomotion.StringVector_assign(self, n, x)

    def resize(self, *args):
        return _BipedalLocomotion.StringVector_resize(self, *args)

    def insert(self, *args):
        return _BipedalLocomotion.StringVector_insert(self, *args)

    def reserve(self, n):
        return _BipedalLocomotion.StringVector_reserve(self, n)

    def capacity(self):
        return _BipedalLocomotion.StringVector_capacity(self)
    __swig_destroy__ = _BipedalLocomotion.delete_StringVector
    __del__ = lambda self: None
StringVector_swigregister = _BipedalLocomotion.StringVector_swigregister
StringVector_swigregister(StringVector)

class IntVector(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, IntVector, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, IntVector, name)
    __repr__ = _swig_repr

    def iterator(self):
        return _BipedalLocomotion.IntVector_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        return _BipedalLocomotion.IntVector___nonzero__(self)

    def __bool__(self):
        return _BipedalLocomotion.IntVector___bool__(self)

    def __len__(self):
        return _BipedalLocomotion.IntVector___len__(self)

    def __getslice__(self, i, j):
        return _BipedalLocomotion.IntVector___getslice__(self, i, j)

    def __setslice__(self, *args):
        return _BipedalLocomotion.IntVector___setslice__(self, *args)

    def __delslice__(self, i, j):
        return _BipedalLocomotion.IntVector___delslice__(self, i, j)

    def __delitem__(self, *args):
        return _BipedalLocomotion.IntVector___delitem__(self, *args)

    def __getitem__(self, *args):
        return _BipedalLocomotion.IntVector___getitem__(self, *args)

    def __setitem__(self, *args):
        return _BipedalLocomotion.IntVector___setitem__(self, *args)

    def pop(self):
        return _BipedalLocomotion.IntVector_pop(self)

    def append(self, x):
        return _BipedalLocomotion.IntVector_append(self, x)

    def empty(self):
        return _BipedalLocomotion.IntVector_empty(self)

    def size(self):
        return _BipedalLocomotion.IntVector_size(self)

    def swap(self, v):
        return _BipedalLocomotion.IntVector_swap(self, v)

    def begin(self):
        return _BipedalLocomotion.IntVector_begin(self)

    def end(self):
        return _BipedalLocomotion.IntVector_end(self)

    def rbegin(self):
        return _BipedalLocomotion.IntVector_rbegin(self)

    def rend(self):
        return _BipedalLocomotion.IntVector_rend(self)

    def clear(self):
        return _BipedalLocomotion.IntVector_clear(self)

    def get_allocator(self):
        return _BipedalLocomotion.IntVector_get_allocator(self)

    def pop_back(self):
        return _BipedalLocomotion.IntVector_pop_back(self)

    def erase(self, *args):
        return _BipedalLocomotion.IntVector_erase(self, *args)

    def __init__(self, *args):
        this = _BipedalLocomotion.new_IntVector(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

    def push_back(self, x):
        return _BipedalLocomotion.IntVector_push_back(self, x)

    def front(self):
        return _BipedalLocomotion.IntVector_front(self)

    def back(self):
        return _BipedalLocomotion.IntVector_back(self)

    def assign(self, n, x):
        return _BipedalLocomotion.IntVector_assign(self, n, x)

    def resize(self, *args):
        return _BipedalLocomotion.IntVector_resize(self, *args)

    def insert(self, *args):
        return _BipedalLocomotion.IntVector_insert(self, *args)

    def reserve(self, n):
        return _BipedalLocomotion.IntVector_reserve(self, n)

    def capacity(self):
        return _BipedalLocomotion.IntVector_capacity(self)
    __swig_destroy__ = _BipedalLocomotion.delete_IntVector
    __del__ = lambda self: None
IntVector_swigregister = _BipedalLocomotion.IntVector_swigregister
IntVector_swigregister(IntVector)

# This file is compatible with both classic and new-style classes.

cc @traversaro and @diegoferigo

I guess that the software headers need to be included two times, once with #include and once with %include, see https://github.com/robotology/idyntree/blob/0e1949b6a9be0c61adf40a0a55dda9df719af7b6/bindings/iDynTree.i#L38 vs https://github.com/robotology/idyntree/blob/0e1949b6a9be0c61adf40a0a55dda9df719af7b6/bindings/iDynTree.i#L162 . The #include specify the header file to include in the generated source file, while the %include the headers that SWIG should process.

You may be interested in https://github.com/rdeits/swig-eigen-numpy as well.

Thank you @traversaro.

Now swig fails with this nice error regarding templates

/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/src/GenericContainer/include/BipedalLocomotion/GenericContainer/TemplateHelpers.h:20: Error: Syntax error in input(1).
bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/build.make:80: recipe for target 'bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx' failed
make[2]: *** [bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx] Error 1
CMakeFiles/Makefile2:984: recipe for target 'bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/all' failed
make[1]: *** [bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/all] Error 2
Makefile:148: recipe for target 'all' failed
make: *** [all] Error 2

https://github.com/dic-iit/bipedal-locomotion-framework/blob/b76c17ff50090012840e6231276ebdc60f580b26/src/GenericContainer/include/BipedalLocomotion/GenericContainer/TemplateHelpers.h#L20

I am afraid that the SWIG support for C++17 syntax is still incomplete: https://github.com/swig/swig/issues/1863 .

I fear that heavily templated libraries, especially with C++17, are quite challenging to bind with SWIG :/

I think that using pybind11 as done in https://github.com/robotology/idyntree/pull/741 would provide a much greater freedom if you plan to target only Python.

If that code is not actually useful to define the interface that you want to wrap with SWIG (perhaps because it is used just internally) you can try to disable it with some #ifdef SWIG or similar.

If that code is not actually useful to define the interface that you want to wrap with SWIG (perhaps because it is used just internally) you can try to disable it with some #ifdef SWIG or similar.

Or, if they do not contain APIs, you can just #include them without using %include. This means that the header is imported while compiling the autogenerated class but SWIG does not parse it to expose its functions to the target language.

I think that using pybind11 as done in robotology/idyntree#741 would provide a much greater freedom if you plan to target only Python.

The idea was to start with python and then extend the bings to Matlab.

If that code is not actually useful to define the interface that you want to wrap with SWIG (perhaps because it is used just internally) you can try to disable it with some #ifdef SWIG or similar.

Unfortunately, it's not so simple, for instance, I need the definition of BipedalLocomotion::GenericContainer::Vector<T>::Ref
https://github.com/dic-iit/bipedal-locomotion-framework/blob/b76c17ff50090012840e6231276ebdc60f580b26/src/GenericContainer/include/BipedalLocomotion/GenericContainer/Vector.h#L906-L907
because it is required in
https://github.com/dic-iit/bipedal-locomotion-framework/blob/b76c17ff50090012840e6231276ebdc60f580b26/src/ParametersHandler/include/BipedalLocomotion/ParametersHandler/StdImplementation.h#L119

however

[ 94%] Swig source
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/src/GenericContainer/include/BipedalLocomotion/GenericContainer/Vector.h:228: Warning 362: operator= ignored
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/src/GenericContainer/include/BipedalLocomotion/GenericContainer/Vector.h:245: Warning 362: operator= ignored
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/src/GenericContainer/include/BipedalLocomotion/GenericContainer/Vector.h:262: Warning 362: operator= ignored
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/src/GenericContainer/include/BipedalLocomotion/GenericContainer/Vector.h:316: Warning 389: operator[] ignored (consider using %extend)
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/src/GenericContainer/include/BipedalLocomotion/GenericContainer/Vector.h:326: Warning 389: operator[] ignored (consider using %extend)
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/src/GenericContainer/include/BipedalLocomotion/GenericContainer/Vector.h:912: Error: Undefined scope 'BipedalLocomotion::GenericContainer::Vector<(T)>'
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/src/GenericContainer/include/BipedalLocomotion/GenericContainer/Vector.h:973: Error: Syntax error in input(3).
bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/build.make:80: recipe for target 'bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx' failed
make[2]: *** [bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx] Error 1
CMakeFiles/Makefile2:984: recipe for target 'bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/all' failed
make[1]: *** [bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/all] Error 2
Makefile:148: recipe for target 'all' failed
make: *** [all] Error 2

Adding

%include "BipedalLocomotion/GenericContainer/Vector.h"

%template(StringVector) BipedalLocomotion::GenericContainer::Vector<std::string>;
%template(IntVector) BipedalLocomotion::GenericContainer::Vector<int>;
%template(DoubleVector) BipedalLocomotion::GenericContainer::Vector<double>;

%template(StringVectorRef) BipedalLocomotion::GenericContainer::Vector<std::string>::Ref;
%template(IntVectorRef) BipedalLocomotion::GenericContainer::Vector<int>::Ref;
%template(DoubleVectorRef) BipedalLocomotion::GenericContainer::Vector<double>::Ref;

did not solve the problem.

For dealing with Eigen, did you checked https://github.com/rdeits/swig-eigen-numpy ? It could contain some interesting pointers.

Anyhow, given the problems that you are experiencing with C++17 and SWIG, and given the interest that I guess we have for also having MATLAB bindings that prevents us from using alternative tools, I wonder if it could make to take a step back and wonder if there could be a better strategy to tackle this problem.

A lot of code in BLF is already strongly block-oriented, in the sense that you have the initialize to pass fixed parameters, you have some methods (not structured) to set the inputs of the dynamical system, you have the advance method to advance the time in the dynamical system, and you have some (not structured) methods to retrieve the outputs. Perhaps a possible strategy is to introduce some structures ways of setting the inputs and the outputs (i.e. a "Block" interface) and then in Python and MATLAB provide only a generic APIs to deal with blocks. In this way the API surface that should be compatible with SWIG (or that needs to be manually exposed to Python and MATLAB) would be minimized.

Here some updates

  1. I had to change this line
    https://github.com/dic-iit/bipedal-locomotion-framework/blob/216d2b0503302d8628129490406cb9652a77b0a2/src/GenericContainer/include/BipedalLocomotion/GenericContainer/Vector.h#L70
    into
    cpp using reference = value_type&
    without changing this line the following error is thrown by swig
<details><summary>Click here to check the content of <b>the error</b></summary>
<p>

```
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx: In instantiation of ‘struct SwigValueWrapper<std::__cxx11::basic_string<char>&>::SwigMovePointer’:
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:28:5:   required from ‘class SwigValueWrapper<std::__cxx11::basic_string<char>&>’
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:4885:64:   required from here
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:24:8: error: forming pointer to reference type ‘std::__cxx11::basic_string<char>&’
     T *ptr;
        ^~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:25:5: error: forming pointer to reference type ‘std::__cxx11::basic_string<char>&’
     SwigMovePointer(T *p) : ptr(p) { }
     ^~~~~~~~~~~~~~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx: In instantiation of ‘class SwigValueWrapper<std::__cxx11::basic_string<char>&>’:
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:4885:64:   required from here
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:35:6: error: forming pointer to reference type ‘std::__cxx11::basic_string<char>&’
   T *operator&() { return pointer.ptr; }
      ^~~~~~~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx: In function ‘PyObject* _wrap_StringVector_at__SWIG_1(PyObject*, Py_ssize_t, PyObject**)’:
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:4911:208: error: new cannot be applied to a reference type
   resultobj = SWIG_NewPointerObj((new BipedalLocomotion::GenericContainer::Vector< std::string >::reference(static_cast< const BipedalLocomotion::GenericContainer::Vector< std::string >::reference& >(result))), SWIGTYPE_p_iDynTree__SpanT_std__string_t__reference, SWIG_POINTER_OWN |  0 );
                                                                                                                                                                                                                ^
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:1093:89: note: in definition of macro ‘SWIG_NewPointerObj’
 #define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
                                                                                         ^~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx: In function ‘PyObject* _wrap_StringVector___call____SWIG_1(PyObject*, Py_ssize_t, PyObject**)’:
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:5037:208: error: new cannot be applied to a reference type
   resultobj = SWIG_NewPointerObj((new BipedalLocomotion::GenericContainer::Vector< std::string >::reference(static_cast< const BipedalLocomotion::GenericContainer::Vector< std::string >::reference& >(result))), SWIGTYPE_p_iDynTree__SpanT_std__string_t__reference, SWIG_POINTER_OWN |  0 );
                                                                                                                                                                                                                ^
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:1093:89: note: in definition of macro ‘SWIG_NewPointerObj’
 #define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
                                                                                         ^~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx: In function ‘PyObject* _wrap_IntVector_at__SWIG_1(PyObject*, Py_ssize_t, PyObject**)’:
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:6169:65: error: ‘result’ declared as reference but not initialized
   BipedalLocomotion::GenericContainer::Vector< int >::reference result;
                                                                 ^~~~~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:6195:192: error: new cannot be applied to a reference type
   resultobj = SWIG_NewPointerObj((new BipedalLocomotion::GenericContainer::Vector< int >::reference(static_cast< const BipedalLocomotion::GenericContainer::Vector< int >::reference& >(result))), SWIGTYPE_p_iDynTree__SpanT_int_t__reference, SWIG_POINTER_OWN |  0 );
                                                                                                                                                                                                ^
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:1093:89: note: in definition of macro ‘SWIG_NewPointerObj’
 #define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
                                                                                         ^~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx: In function ‘PyObject* _wrap_IntVector___call____SWIG_1(PyObject*, Py_ssize_t, PyObject**)’:
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:6295:65: error: ‘result’ declared as reference but not initialized
   BipedalLocomotion::GenericContainer::Vector< int >::reference result;
                                                                 ^~~~~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:6321:192: error: new cannot be applied to a reference type
   resultobj = SWIG_NewPointerObj((new BipedalLocomotion::GenericContainer::Vector< int >::reference(static_cast< const BipedalLocomotion::GenericContainer::Vector< int >::reference& >(result))), SWIGTYPE_p_iDynTree__SpanT_int_t__reference, SWIG_POINTER_OWN |  0 );
                                                                                                                                                                                                ^
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:1093:89: note: in definition of macro ‘SWIG_NewPointerObj’
 #define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
                                                                                         ^~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx: In function ‘PyObject* _wrap_DoubleVector_at__SWIG_1(PyObject*, Py_ssize_t, PyObject**)’:
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:7453:68: error: ‘result’ declared as reference but not initialized
   BipedalLocomotion::GenericContainer::Vector< double >::reference result;
                                                                    ^~~~~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:7479:198: error: new cannot be applied to a reference type
   resultobj = SWIG_NewPointerObj((new BipedalLocomotion::GenericContainer::Vector< double >::reference(static_cast< const BipedalLocomotion::GenericContainer::Vector< double >::reference& >(result))), SWIGTYPE_p_iDynTree__SpanT_double_t__reference, SWIG_POINTER_OWN |  0 );
                                                                                                                                                                                                      ^
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:1093:89: note: in definition of macro ‘SWIG_NewPointerObj’
 #define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
                                                                                         ^~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx: In function ‘PyObject* _wrap_DoubleVector___call____SWIG_1(PyObject*, Py_ssize_t, PyObject**)’:
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:7579:68: error: ‘result’ declared as reference but not initialized
   BipedalLocomotion::GenericContainer::Vector< double >::reference result;
                                                                    ^~~~~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:7605:198: error: new cannot be applied to a reference type
   resultobj = SWIG_NewPointerObj((new BipedalLocomotion::GenericContainer::Vector< double >::reference(static_cast< const BipedalLocomotion::GenericContainer::Vector< double >::reference& >(result))), SWIGTYPE_p_iDynTree__SpanT_double_t__reference, SWIG_POINTER_OWN |  0 );
                                                                                                                                                                                                      ^
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:1093:89: note: in definition of macro ‘SWIG_NewPointerObj’
 #define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
                                                                                         ^~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx: In instantiation of ‘SwigValueWrapper<T>::SwigValueWrapper() [with T = std::__cxx11::basic_string<char>&]’:
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:4885:64:   required from here
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:32:33: error: no matching function for call to ‘SwigValueWrapper<std::__cxx11::basic_string<char>&>::SwigMovePointer::SwigMovePointer(int)’
   SwigValueWrapper() : pointer(0) { }
                                 ^
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:23:10: note: candidate: constexpr SwigValueWrapper<std::__cxx11::basic_string<char>&>::SwigMovePointer::SwigMovePointer()
   struct SwigMovePointer {
          ^~~~~~~~~~~~~~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:23:10: note:   candidate expects 0 arguments, 1 provided
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:23:10: note: candidate: constexpr SwigValueWrapper<std::__cxx11::basic_string<char>&>::SwigMovePointer::SwigMovePointer(const SwigValueWrapper<std::__cxx11::basic_string<char>&>::SwigMovePointer&)
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:23:10: note:   no known conversion for argument 1 from ‘int’ to ‘const SwigValueWrapper<std::__cxx11::basic_string<char>&>::SwigMovePointer&’
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx: In instantiation of ‘SwigValueWrapper<T>::SwigMovePointer::~SwigMovePointer() [with T = std::__cxx11::basic_string<char>&]’:
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:22:28:   required from here
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:26:33: error: using invalid field ‘SwigValueWrapper<T>::SwigMovePointer::ptr’
     ~SwigMovePointer() { delete ptr; }
                                 ^~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx: In instantiation of ‘SwigValueWrapper<T>& SwigValueWrapper<T>::operator=(const T&) [with T = std::__cxx11::basic_string<char>&]’:
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:4908:29:   required from here
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:33:65: error: new cannot be applied to a reference type
   SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; }
                                                                 ^~~~~~~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:33:61: error: no matching function for call to ‘SwigValueWrapper<std::__cxx11::basic_string<char>&>::SwigMovePointer::SwigMovePointer(std::__cxx11::basic_string<char>*)’
   SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; }
                                                             ^~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:23:10: note: candidate: constexpr SwigValueWrapper<std::__cxx11::basic_string<char>&>::SwigMovePointer::SwigMovePointer()
   struct SwigMovePointer {
          ^~~~~~~~~~~~~~~
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:23:10: note:   candidate expects 0 arguments, 1 provided
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:23:10: note: candidate: constexpr SwigValueWrapper<std::__cxx11::basic_string<char>&>::SwigMovePointer::SwigMovePointer(const SwigValueWrapper<std::__cxx11::basic_string<char>&>::SwigMovePointer&)
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:23:10: note:   no known conversion for argument 1 from ‘std::__cxx11::basic_string<char>*’ to ‘const SwigValueWrapper<std::__cxx11::basic_string<char>&>::SwigMovePointer&’
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx: In instantiation of ‘SwigValueWrapper<T>::operator T&() const [with T = std::__cxx11::basic_string<char>&]’:
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:4911:15:   required from here
/home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:34:41: error: ‘const struct SwigValueWrapper<std::__cxx11::basic_string<char>&>::SwigMovePointer’ has no member named ‘ptr’
   operator T&() const { return *pointer.ptr; }
                                 ~~~~~~~~^~~
bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/build.make:89: recipe for target 'bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/BipedalLocomotionFrameworkPYTHON_wrap.cxx.o' failed
make[2]: *** [bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/BipedalLocomotionFrameworkPYTHON_wrap.cxx.o] Error 1
CMakeFiles/Makefile2:984: recipe for target 'bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/all' failed
make[1]: *** [bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/all] Error 2
Makefile:148: recipe for target 'all' failed
make: *** [all] Error 2
```


  1. As soon as I include BipedalLocomotion/ParametersHandler/IParametersHandler.h I got the following error

    Click here to check the content of the error

    /home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx: In function ‘PyObject* _wrap_IParametersHandler_getParameter__SWIG_5(PyObject*, Py_ssize_t, PyObject**)’:
    /home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:8636:59: error: use of deleted function ‘BipedalLocomotion::GenericContainer::Vector<T>::Ref::Ref() [with T = int]’
       BipedalLocomotion::GenericContainer::Vector< int >::Ref arg3 ;
                                                               ^~~~
    In file included from /home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:2869:0:
    /home/gromualdi/robot-code/bipedal-locomotion-framework_swig/src/GenericContainer/include/BipedalLocomotion/GenericContainer/Vector.h:928:5: note: declared here
         Ref() = delete;
         ^~~
    /home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx: In function ‘PyObject* _wrap_IParametersHandler_getParameter__SWIG_6(PyObject*, Py_ssize_t, PyObject**)’:
    /home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:8692:62: error: use of deleted function ‘BipedalLocomotion::GenericContainer::Vector<T>::Ref::Ref() [with T = double]’
       BipedalLocomotion::GenericContainer::Vector< double >::Ref arg3 ;
                                                                  ^~~~
    In file included from /home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:2869:0:
    /home/gromualdi/robot-code/bipedal-locomotion-framework_swig/src/GenericContainer/include/BipedalLocomotion/GenericContainer/Vector.h:928:5: note: declared here
         Ref() = delete;
         ^~~
    /home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx: In function ‘PyObject* _wrap_IParametersHandler_getParameter__SWIG_7(PyObject*, Py_ssize_t, PyObject**)’:
    /home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:8748:67: error: use of deleted function ‘BipedalLocomotion::GenericContainer::Vector<T>::Ref::Ref() [with T = std::__cxx11::basic_string<char>]’
       BipedalLocomotion::GenericContainer::Vector< std::string >::Ref arg3 ;
                                                                       ^~~~
    In file included from /home/gromualdi/robot-code/bipedal-locomotion-framework_swig/build/bindings/python/BipedalLocomotionFrameworkPYTHON_wrap.cxx:2869:0:
    /home/gromualdi/robot-code/bipedal-locomotion-framework_swig/src/GenericContainer/include/BipedalLocomotion/GenericContainer/Vector.h:928:5: note: declared here
         Ref() = delete;
         ^~~
    bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/build.make:89: recipe for target 'bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/BipedalLocomotionFrameworkPYTHON_wrap.cxx.o' failed
    make[2]: *** [bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/BipedalLocomotionFrameworkPYTHON_wrap.cxx.o] Error 1
    CMakeFiles/Makefile2:984: recipe for target 'bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/all' failed
    make[1]: *** [bindings/python/CMakeFiles/_BipedalLocomotion_python.dir/all] Error 2
    Makefile:148: recipe for target 'all' failed
    make: *** [all] Error 2
    


    Indeed the Ref default constructor is deleted in

    https://github.com/dic-iit/bipedal-locomotion-framework/blob/216d2b0503302d8628129490406cb9652a77b0a2/src/GenericContainer/include/BipedalLocomotion/GenericContainer/Vector.h#L914

@traversaro, @diegoferigo do you know why this is happening?

This comment refers to 593dd18c14438340c35b292f358b9ca29829431c

Edit: I'm afraid that the problem is related to the nested classes

Note that the SWIG 4 documentation is available at http://www.swig.org/Doc4.0/SWIGPlus.html#SWIGPlus_nested_classes .

I am afraid that SWIG needs to create a temporary object of Type ref for its code generation to work. A possible way to tackle this is to directly go on and provide typemaps (http://www.swig.org/Doc4.0/SWIGDocumentation.html#Arguments_nn2) to convert directly Ref elements to the equivalent Python types, or ignore the methods that take in input or output Ref types (if this is possible at all).

Another codebase using Eigen+SWIG was https://github.com/robot-locomotion/dwl/blob/b45e6babfcace928af2601f3d453e3f27e2e76c8/swig/eigen.i#L626 , but I guess also there they use typemaps.

134 closes the issue

Was this page helpful?
0 / 5 - 0 ratings