简体   繁体   中英

How to access declared template structure variables in SWIG?

I am trying to generate a file of Python definitions from C++ using SWIG 3.0.5. These definitions are templated structures, defined in my toy foo.h as:

template<typename T> struct LimitDef
{
    T min;
    T max;
    int otherstuff;
    int etc;
}

namespace ProjectLimits
{
    const LimitDef<int>    Limit1 = {  -5, 100, 42,  0};
    const LimitDef<double> Limit2 = {-1.0, 1.0,  0, 42};
    ...
}

In my corresponding foo.i SWIG interface I have:

%module foo
%{
#include "foo.h"
%}

%include "foo.h"

%template(LimitDef_int) LimitDef<int>;
%template(LimitDef_double) LimitDef<double>;

Compiled to Python, I can access the newly instantiated template names (and create new LimitDef_int objects with no issue), and I can see the declared Limit# variables, but the types don't line up -- the already-declared vars are bare, inaccessible object pointers with no __swig_getmethods__ etc:

>>> import foo
>>> newlim = foo.LimitDef_int()
>>> newlim.min = 5
>>> print newlim.min
5
>>> print newlim
<foo.LimitDef_int; proxy of <Swig Object of type 'LimitDef< int > *' at 0x17f2338> >
>>> foo.Limit1
<Swig Object of type 'LimitDef< int> *' at 0x17f2b30>
>>> print foo.Limit1.min
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'SwigPyObject' object has no attribute 'min'
>>> dir(foo.Limit1.min)
['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__hex__', '__init__', '__int__', '__le__', '__long__', '__lt__', '__ne__', '__new__', '__oct__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'acquire', 'append', 'disown', 'next', 'own']

I've tried moving the %template directives to before %include "foo.h" so that the new instantiated template definitions are in place when the declared vars are parsed, but then I get Error: Template 'LimitDef' undefined when I try to build.

I've tried %extend ing the specific template types to provide accessors (as that's all I really need) eg:

%extend LimitDef<int> {
    int get_min() { return (*$self).min; }
};

But again, this applies only to the newly-created LimitDef_int type and its instances; Limit1 etc. are unaffected (even when the %extend block is before %include "foo.h" ).

I don't care so much about creating new instances as I am being able to access those existing Limit# variables. If at all possible I don't want to modify the source; my actual project file has 100+ such constants defined.

What am I missing that will allow me to have foo.Limit1.min return -5 ?

SWIG Manual - 36.3.3 [Python; Global variables]

To provide access to C global variables, SWIG creates a special object called cvar that is added to each SWIG generated module. Global variables are then accessed as attributes of this object.

So the proxy object for Limit1 can be found at foo.cvar.Limit1 .

See also How C/C++ global variables are implemented in python?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM