我们使用SWIG在C ++中包装我们的类并在Python中使用它们。我们所拥有的是C ++中的一个方法,它返回一个包含我们自定义类对象的向量,比如说Foo。基本上,我们使用SWIG包装了以下方法:
std::vector<Foo> my_cpp_method(char *);
在SWIG .i文件中,我们有
%module wrapper
%{
...
%}
%include ...
...
namespace std {
...
%template(vector_foo) vector<Foo>;
...
}
现在,使用python时遇到的问题是:
my_list = wrapper.my_cpp_method()
o = my_list[0]
# The following works as expected
print o.value # assume class Foo has a property called value
# Now the issue
my_list = None
gc.collect()
print o.value # prints garbage
基本上,只要my_list设置为None,向量就会被垃圾收集及其内容。当我说o = my_list[0]
时,我希望通过在Foo上使用复制构造函数,我得到my_list[0]
的内容的副本(不是在python中,但我希望swig能为我做到这一点),并且因此将列表设置为None不会让我留下悬空指针。
有没有办法可以强制SWIG始终在Foo上调用复制构造函数,并返回一个关于访问列表(作为包装向量)成员的副本,这样我就可以理所当然地使用{{1}返回的列表像一个普通的python列表,而不必担心悬空指针?
编辑:关于在python中迭代SWIG包装的向量的有趣发现。只是想提一下,因为看起来SWIG确实提供了一种创建副本的方法,而不是在你使用[]操作符直接访问时。 PS:我们正在使用它作为上述问题的解决方法,但我希望有人可以使用SWIG提供更强大和语义正确/干净的处理方法。再次考虑与上述相同的设置。
my_cpp_method