大佬教程收集整理的这篇文章主要介绍了SWIG,C和Python:C临时对象过早删除,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
-------------------------------------------------------------------------------- Works as expected: b0 = Buffer(0,) b1 = Buffer(1,1,) b0 = Buffer(0,) y = Buffer(0,) repr(b0) = Buffer(id = 0,vector at 0x020bf450,data at 0x020aeb30,size = 6) repr(y) = Buffer(id = 0,size = 6) Funny business: deleting Buffer(id = 2) deleting Buffer(id = 3) repr(b2) = Buffer(id = 2,vector at 0x020bf790,data at 0x00,size = 4257068) deleting Buffer(id = 4) repr(b3) = Buffer(id = 4,vector at 0x02037040,data at 0x0204a4e0,size = 6) deleting Buffer(id = 0) deleting Buffer(id = 1)
删除缓冲区(id = X)是从Buffer :: ~Buffer()C代码中生成的,所以我们在这里可以看到,在Funny业务部分,C Buffer对象被过早删除了! Python对象b2和b3应该保持对id = 2和id = 4的C Buffer对象的引用.
我的所有代码都附在我的博客post上.但是,我将在这里总结一下代码:
Buffer.hpp:
#include <vector> #include <String> struct Buffer { Buffer(); Buffer(const Buffer & copy); ~Buffer(); Buffer & operator=(const Buffer & rhs); Buffer & operator<<(const Buffer & rhs); Buffer & operator<<(double rhs); std::string __str__() const; std::string __repr__() const; private: std::vector<double> _data; int _id; };
swig_test.i:
%module swig_test %include "std_String.i" %{ #include "Buffer.hpp" #include <iostream> %} %ignore Buffer::operator=; %include "Buffer.hpp"
go_test.py:
from swig_test import Buffer def zeros(n): ''' Returns a Buffer filled with 'n' zeros. ''' b = Buffer() for i in xrange(n): b << 0.0 return b def ones(n): ''' Returns a Buffer filled with 'n' ones. ''' b = Buffer() for i in xrange(n): b << 1.0 return b def main(): #-------------------------------------------------------------------------- # This sections works as expected print "-" * 80 print "Works as expected:" b0 = zeros(3) print " b0 = ",b0 b1 = ones(3) print " b1 = ",b1 y = b0 << b1 print " b0 = ",b0 print " y = ",y print " b1 = ",b1 print " repr(b0) = ",repr(b0) print " repr(y) = ",repr(y) #-------------------------------------------------------------------------- # Funny things are happening here! print "Funny business:" b2 = zeros(3) << ones(3) print " repr(b2) = ",repr(b2) b3 = zeros(3) << 4.0 print " repr(b3) = ",repr(b3) if __name__ == "__main__": main()
我在博客文章中已经尝试了一些SWIG的东西,但我的SWIG-foo技能已经缩短了.
救救我社区,你是我唯一的希望!
更新1
我怀疑我有多个PyObjects将Buffer *保存到同一个C Buffer对象,所以当临时PyObject被垃圾收集时,它会删除C Buffer *.
所以,我想我需要一个Py_INCREF,但在哪里呢?
更新2
尝试按照jarod42的建议按值返回会破坏串联范例,例如:
b = Buffer() b << 1 << 2 << 3 print b
只生产:
Buffer(1,)
所以这不是我想要的.
%newobject指令可用于释放函数或方法创建的新创建的对象(防止内存泄漏).在这种情况下,Buffer :: operator<<没有创建新对象.
将typemap(out)与Py_INCREF结合使用就可以了.
swig_test.i:
%module swig_test %include "std_String.i" %{ #include "Buffer.hpp" #include <iostream> %} %ignore Buffer::operator=; %typemap(out) Buffer & operator<< { if(result) { /* suppress unused warning */ } Py_INCREF($self); $result = $self; } %include "Buffer.hpp"
现在我得到了我想要的行为(它与纯Python实现相匹配)并且没有内存泄漏.
以上是大佬教程为你收集整理的SWIG,C和Python:C临时对象过早删除全部内容,希望文章能够帮你解决SWIG,C和Python:C临时对象过早删除所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。