在 C++ 结构中对 std::vector 成员使用 SWIG
Using SWIG for std::vector members in C++ structs
我正在尝试使用 SWIG 包装包含向量成员的 C++ 结构,并提供与 Python 的接口。我有一个使用以下三个文件的小测试用例 (Ubuntu-16.04):
一个看起来像这样的 Makefile:
FLAGS = -fPIC
PYTHONI = -I /usr/include/python3.5/
PYTHONL = -Xlinker -export-dynamic
all:
swig -Wall -c++ -python -o test.cxx test.i
g++ $(FLAGS) $(PYTHONI) -c test.cxx -o test_wrap.o
g++ $(PYTHONL) $(LIBFLAGS) -shared -o _test.so test_wrap.o -lstdc++
测试 C++ header 在此处定义结构 (test.h):
#ifndef TEST_H
#define TEST_H
#include <vector>
using std :: vector;
struct myStruct {
float var1; // m
vector<float> arr1; // m
vector<float> arr2; // C
int var2;
};
#endif
这里还有一个 SWIG 接口文件 (test.i):
%module test
%include "std_vector.i"
typedef std::vector<float> FloatVector;
namespace std {
%template(FloatVector) vector<float>;
};
%naturalvar myStruct::arr1;
%{
#include <vector>
#include "test.h"
%}
%include "test.h"
运行 make all 创建一个 test.py 文件,可以导入并创建 myStruct class:
import test
foo = test.myStruct()
我可以像这样调用设置 var1 和 var2 成员:
foo.var1 = 1.23
foo.var2 = 4
但是,我无法对 arr1 或 arr2 成员进行编辑。这些都是 'SwigPyObject' 类型,即使我尝试在 arr1 上使用 %naturalvar
。我想要做的是创建一个结构,用我的 Python session 中的数据填充它,然后在对 C++ 函数的其他调用中使用该结构。
在头文件中使用 using
是个坏主意。 SwigPyObject
类型表示类型映射不正确匹配。例如,这有效:
test.i:
%module test
%include <std_vector.i>
%template(FloatVector) std::vector<float>;
%naturalvar myStruct::arr1;
%naturalvar myStruct::arr2;
%inline %{
#include <vector>
struct myStruct {
float var1;
std::vector<float> arr1;
std::vector<float> arr2;
int var2;
};
%}
演示:
>>> import test
>>> foo = test.myStruct()
>>> foo.arr1
()
>>> foo.var1=1.23
>>> foo.var2=5
>>> foo.arr1=1,2,3
>>> foo.arr2=1.1,2.2
>>> foo
<test.myStruct; proxy of <Swig Object of type 'myStruct *' at 0x000001F94E7487E0> >
>>> foo.var1
1.2300000190734863
>>> foo.var2
5
>>> foo.arr1
(1.0, 2.0, 3.0)
>>> foo.arr2
(1.100000023841858, 2.200000047683716)
没有 %naturalvar
仍然可以分配值,但需要:
>>> foo.arr1 = test.FloatVector([1,2,3])
我正在尝试使用 SWIG 包装包含向量成员的 C++ 结构,并提供与 Python 的接口。我有一个使用以下三个文件的小测试用例 (Ubuntu-16.04):
一个看起来像这样的 Makefile:
FLAGS = -fPIC
PYTHONI = -I /usr/include/python3.5/
PYTHONL = -Xlinker -export-dynamic
all:
swig -Wall -c++ -python -o test.cxx test.i
g++ $(FLAGS) $(PYTHONI) -c test.cxx -o test_wrap.o
g++ $(PYTHONL) $(LIBFLAGS) -shared -o _test.so test_wrap.o -lstdc++
测试 C++ header 在此处定义结构 (test.h):
#ifndef TEST_H
#define TEST_H
#include <vector>
using std :: vector;
struct myStruct {
float var1; // m
vector<float> arr1; // m
vector<float> arr2; // C
int var2;
};
#endif
这里还有一个 SWIG 接口文件 (test.i):
%module test
%include "std_vector.i"
typedef std::vector<float> FloatVector;
namespace std {
%template(FloatVector) vector<float>;
};
%naturalvar myStruct::arr1;
%{
#include <vector>
#include "test.h"
%}
%include "test.h"
运行 make all 创建一个 test.py 文件,可以导入并创建 myStruct class:
import test
foo = test.myStruct()
我可以像这样调用设置 var1 和 var2 成员:
foo.var1 = 1.23
foo.var2 = 4
但是,我无法对 arr1 或 arr2 成员进行编辑。这些都是 'SwigPyObject' 类型,即使我尝试在 arr1 上使用 %naturalvar
。我想要做的是创建一个结构,用我的 Python session 中的数据填充它,然后在对 C++ 函数的其他调用中使用该结构。
在头文件中使用 using
是个坏主意。 SwigPyObject
类型表示类型映射不正确匹配。例如,这有效:
test.i:
%module test
%include <std_vector.i>
%template(FloatVector) std::vector<float>;
%naturalvar myStruct::arr1;
%naturalvar myStruct::arr2;
%inline %{
#include <vector>
struct myStruct {
float var1;
std::vector<float> arr1;
std::vector<float> arr2;
int var2;
};
%}
演示:
>>> import test
>>> foo = test.myStruct()
>>> foo.arr1
()
>>> foo.var1=1.23
>>> foo.var2=5
>>> foo.arr1=1,2,3
>>> foo.arr2=1.1,2.2
>>> foo
<test.myStruct; proxy of <Swig Object of type 'myStruct *' at 0x000001F94E7487E0> >
>>> foo.var1
1.2300000190734863
>>> foo.var2
5
>>> foo.arr1
(1.0, 2.0, 3.0)
>>> foo.arr2
(1.100000023841858, 2.200000047683716)
没有 %naturalvar
仍然可以分配值,但需要:
>>> foo.arr1 = test.FloatVector([1,2,3])