简体   繁体   English

如何在SWIG中访问声明的模板结构变量?

[英]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. 我正在尝试使用SWIG 3.0.5从C ++生成Python定义文件。 These definitions are templated structures, defined in my toy foo.h as: 这些定义是模板结构,在我的玩具foo.h定义为:

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: 在我对应的foo.i SWIG界面中,我有:

%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: 编译为Python后,我可以访问新实例化的模板名称(并可以LimitDef_int创建新的LimitDef_int对象),并且可以看到已声明的Limit#变量,但类型却不LimitDef_int -已经声明的var只是裸露的,没有__swig_getmethods__等的无法访问的对象指针:

>>> 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. 我尝试将%template指令移动到%include "foo.h"以便在解析声明的var时使用新的实例化模板定义,但是随后出现Error: Template 'LimitDef' undefined尝试使用Error: Template 'LimitDef' undefined建立。

I've tried %extend ing the specific template types to provide accessors (as that's all I really need) eg: 我已经尝试了%extend特定的模板类型来提供访问器(这是我真正需要的),例如:

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

But again, this applies only to the newly-created LimitDef_int type and its instances; 但同样,这仅适用于新创建的LimitDef_int类型及其实例。 Limit1 etc. are unaffected (even when the %extend block is before %include "foo.h" ). Limit1等不受影响(即使%extend块位于%include "foo.h" )。

I don't care so much about creating new instances as I am being able to access those existing Limit# variables. 我不太在意创建新实例,因为我能够访问那些现有的Limit#变量。 If at all possible I don't want to modify the source; 如果可能的话,我不想修改源代码。 my actual project file has 100+ such constants defined. 我的实际项目文件定义了100多个这样的常量。

What am I missing that will allow me to have foo.Limit1.min return -5 ? 我缺少什么让我有foo.Limit1.min return -5

SWIG Manual - 36.3.3 [Python; SWIG手册-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. 为了提供对C全局变量的访问,SWIG创建一个名为cvar的特殊对象,该对象将添加到每个SWIG生成的模块中。 Global variables are then accessed as attributes of this object. 然后访问全局变量作为该对象的属性。

So the proxy object for Limit1 can be found at foo.cvar.Limit1 . 所以对于代理对象Limit1 ,可以发现foo.cvar.Limit1

See also How C/C++ global variables are implemented in python? 另请参见如何在python中实现C / C ++全局变量?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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