如何访问 SWIG 中声明的模板结构变量?
How to access declared template structure variables in SWIG?
我正在尝试使用 SWIG 3.0.5 从 C++ 生成一个包含 Python 定义的文件。这些定义是模板化结构,在我的玩具 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};
...
}
在我对应的 foo.i
SWIG 接口中我有:
%module foo
%{
#include "foo.h"
%}
%include "foo.h"
%template(LimitDef_int) LimitDef<int>;
%template(LimitDef_double) LimitDef<double>;
编译为 Python,我可以访问新实例化的模板名称(并毫无问题地创建新的 LimitDef_int
对象),并且我可以看到声明的 Limit#
变量,但是类型不一致——已经声明的变量是裸露的、不可访问的对象指针,没有 __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']
我尝试将 %template
指令移动到 %include "foo.h"
之前,以便在解析声明的变量时新的实例化模板定义就位,但后来我得到 Error: Template 'LimitDef' undefined
当我尝试构建时。
我已经尝试 %extend
ing 特定模板类型来提供访问器(因为这就是我真正需要的)例如:
%extend LimitDef<int> {
int get_min() { return (*$self).min; }
};
但同样,这仅适用于新创建的 LimitDef_int
类型及其实例; Limit1
等不受影响(即使 %extend
块在 %include "foo.h"
之前)。
我不太关心创建新实例,因为我能够访问那些现有的 Limit#
变量。如果可能的话,我不想修改源代码;我的实际项目文件定义了 100 多个这样的常量。
我缺少什么能让我拥有 foo.Limit1.min
return -5
?
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. Global variables are then accessed as attributes of this object.
因此 Limit1
的代理对象可以在 foo.cvar.Limit1
找到。
另见 How C/C++ global variables are implemented in python?
我正在尝试使用 SWIG 3.0.5 从 C++ 生成一个包含 Python 定义的文件。这些定义是模板化结构,在我的玩具 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};
...
}
在我对应的 foo.i
SWIG 接口中我有:
%module foo
%{
#include "foo.h"
%}
%include "foo.h"
%template(LimitDef_int) LimitDef<int>;
%template(LimitDef_double) LimitDef<double>;
编译为 Python,我可以访问新实例化的模板名称(并毫无问题地创建新的 LimitDef_int
对象),并且我可以看到声明的 Limit#
变量,但是类型不一致——已经声明的变量是裸露的、不可访问的对象指针,没有 __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']
我尝试将 %template
指令移动到 %include "foo.h"
之前,以便在解析声明的变量时新的实例化模板定义就位,但后来我得到 Error: Template 'LimitDef' undefined
当我尝试构建时。
我已经尝试 %extend
ing 特定模板类型来提供访问器(因为这就是我真正需要的)例如:
%extend LimitDef<int> {
int get_min() { return (*$self).min; }
};
但同样,这仅适用于新创建的 LimitDef_int
类型及其实例; Limit1
等不受影响(即使 %extend
块在 %include "foo.h"
之前)。
我不太关心创建新实例,因为我能够访问那些现有的 Limit#
变量。如果可能的话,我不想修改源代码;我的实际项目文件定义了 100 多个这样的常量。
我缺少什么能让我拥有 foo.Limit1.min
return -5
?
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. Global variables are then accessed as attributes of this object.
因此 Limit1
的代理对象可以在 foo.cvar.Limit1
找到。
另见 How C/C++ global variables are implemented in python?