我有一个std::vector<CameraT>
,由于Flexo对SWIG and C++ memory leak with vector of pointers的响应,我已经将其绑定到Python。但我需要访问像CameraT.t这样的字段,而且我找不到合适的方法。在
它在第三方头文件(DataInterface.h)中定义为:
template<class FT>
struct CameraT_ {
typedef FT float_t;
float_t t[3];
/* more elaborate c++ stuff */
};
typedef CameraT_<float> CameraT;
接口文件大致如下所示:
^{pr2}$以及集成测试:
import nvm
if __name__ == "__main__":
datafile = '../../example-data/vidstills.nvm'
cams = nvm.CamVector()
assert nvm.CameraDataFromNVM(datafile, cams)
print(cams[0]) # this yields no memory warnings
print(cams[0].t[0]) # 'SwigPyObject' object has no attribute 't'
# Yields: swig/python detected a memory leak of type 'CameraT *', no destructor found.
c = list([i for i in cams])
打印此:
$ python3 test_nvm.py |& head
<Swig Object of type 'CameraT *' at 0x7f638228ee40>
Loading cameras/points: ../../example-data/vidstills.nvm
329 cameras; 8714 3D points; 74316 projections
Traceback (most recent call last):
File "test_nvm.py", line 20, in <module>
print(cams[0].t[0])
AttributeError: 'SwigPyObject' object has no attribute 't'
swig/python detected a memory leak of type 'CameraT *', no destructor found.
我试图将struct CameraT {}
和#include
语句放在%inline块内外,但失败了。在向量元素上循环也会产生内存泄漏警告。不知道还能做什么。在
代码位于Github。在
这里有几个问题。首先,要修复有关内存泄漏的警告,您需要
%include "datainterface.h"
,然后对CameraT_
模板使用另一条%template
指令。(typedef不会改变这是必需的这一事实)。在因此:
警告消失,我们可以访问该类型的成员。(在您提到的示例的第一行中没有警告,这是Python引用计数系统的一个怪癖)。在
不过,还不止这些,我们现在得到一个关于
^{pr2}$t
不可订阅的错误。我们可以通过调用swig和-debug tmsearch作为一个额外的参数来深入了解这一点,它显示了正在选择的类型映射。最重要的是,我们看到的是:稍微令人惊讶的是,我在SWIG头中都找不到合适的类型映射。(它当然存在于Java中,但在arrays\u Java.i中)。有几种方法可以修复它:
由于1和2是微不足道的,不是很好的Python,我将跳过它们,为我们编写一两个类型映射,我最后的nvm.I文件最终看起来像:
这样我就可以用我的地址运行你的测试文件了:
这个解决方案有一个警告,它是可以解决的(通过返回一个代理对象),但不会自动破坏交易:
这是因为我们返回了一个新的Python元组,其中有一个{{4CD>}的副本,所以这里的第二个下标操作符是指这个,而不是原来的C++数据。{{6}如果你想用一个cdtuple}来修复一个cdtuple}的实现。有一个速度/复杂性的权衡取决于你期望如何使用代码。我有an example of something similar to this,您需要调整out typemap来创建一个
wrapped_array
,并调整wrapped_数组来保存指向实际数组的指针(以及对Python对象的引用,这样它就不会以错误的顺序释放)。在相关问题 更多 >
编程相关推荐