问题描述
我试图使用 boost :: shared_ptr
允许我在我的python脚本中使用c ++文件I / O流对象。
这是一个最小的 .i
文件展示的问题:
%module ptrtest
%includeboost_shared_ptr.i
%include std_string.i
%shared_ptr(std :: ofstream)
%{
#include< fstream&
#include< boost / shared_ptr.hpp>
typedef boost :: shared_ptr< std :: ofstream> ofstream_ptr;
ofstream_ptr mk_out(const std :: string& fname){
return ofstream_ptr(new std :: ofstream(fname.c_str()));
}
%}
ofstream_ptr mk_out(const std :: string& fname);
%pythoncode%{
def leak_memory():
''演示函数 - 当我调用
this,I获取有关内存泄漏的警告
'''
ostr = mk_out('/ tmp / dont_do_this.txt')
%}
以下是警告:
In [2]:ptrtest.leak_memory()
swig / python检测到'ofstream_ptr *'类型的内存泄漏,找不到析构函数。
是否有办法修改 .i
文件告诉界面如何正确处理shared_ptr?
您的示例缺少两个部分来获取析构函数运行:
-
由于SWIG完全不了解
std :: ofstream
默认行为是除了通过一个不透明句柄之外什么都不做。有关这方面的进一步讨论,请参见。
此处的修复是为您的接口文件中的
std :: ofstream
提供一个空定义,以说服SWIG -
SWIG需要查看typedef本身 - 在<$ c $
因此你的例子成为:
%module ptrtest
% boost_shared_ptr.i
%includestd_string.i
%shared_ptr(std :: ofstream)
命名空间std {
class ofstream {
};
}
%{
#include< fstream>
#include< boost / shared_ptr.hpp>
typedef boost :: shared_ptr< std :: ofstream> ofstream_ptr;
ofstream_ptr mk_out(const std :: string& fname){
return ofstream_ptr(new std :: ofstream(fname.c_str()));
}
%}
typedef boost :: shared_ptr< std :: ofstream> ofstream_ptr;
ofstream_ptr mk_out(const std :: string& fname);
%pythoncode%{
def leak_memory():
ostr = mk_out('/ tmp / dont_do_this.txt')
%}
为了将来的参考,你可以避免重复的东西,只存在.i文件与%inline
:
%inline%{
typedef boost :: shared_ptr< std :: ofstream> ofstream_ptr;
ofstream_ptr mk_out(const std :: string& fname){
return ofstream_ptr(new std :: ofstream(fname.c_str()));
}
%}
它声明,定义和
I'm trying to use boost::shared_ptr
's to allow for me to use c++ file I/O stream objects in my python script. However, the generated wrapper warns me that it is leaking memory.
Here's a minimal .i
file exhibiting the problem:
%module ptrtest
%include "boost_shared_ptr.i"
%include "std_string.i"
%shared_ptr( std::ofstream )
%{
#include <fstream>
#include <boost/shared_ptr.hpp>
typedef boost::shared_ptr< std::ofstream > ofstream_ptr;
ofstream_ptr mk_out(const std::string& fname ){
return ofstream_ptr( new std::ofstream( fname.c_str() ) );
}
%}
ofstream_ptr mk_out(const std::string& fname );
%pythoncode %{
def leak_memory():
''' demonstration function -- when I call
this, I get a warning about memory leaks
''''
ostr=mk_out('/tmp/dont_do_this.txt')
%}
Here's the warning:
In [2]: ptrtest.leak_memory()
swig/python detected a memory leak of type 'ofstream_ptr *', no destructor found.
Is there a way to modify the .i
file to tell the interface how to dispose of the shared_ptr properly?
Your example is missing two parts to get the destructor to run:
Since SWIG knows absolutely nothing about
std::ofstream
the default behaviour is to do nothing beyond pass an opaque handle around. See another answer of mine for a further discussion of this.The fix here is to supply an empty definition for
std::ofstream
in your interface file to convince SWIG it knows enough to do more, even if you don't plan on exposing any members.SWIG needs to see the typedef itself - inside the
%{ %}
it just gets passed straight to the output module, not used in the wraping itself.
Thus your example becomes:
%module ptrtest
%include "boost_shared_ptr.i"
%include "std_string.i"
%shared_ptr( std::ofstream )
namespace std {
class ofstream {
};
}
%{
#include <fstream>
#include <boost/shared_ptr.hpp>
typedef boost::shared_ptr< std::ofstream > ofstream_ptr;
ofstream_ptr mk_out(const std::string& fname ){
return ofstream_ptr( new std::ofstream( fname.c_str() ) );
}
%}
typedef boost::shared_ptr< std::ofstream > ofstream_ptr;
ofstream_ptr mk_out(const std::string& fname );
%pythoncode %{
def leak_memory():
ostr=mk_out('/tmp/dont_do_this.txt')
%}
For future reference you can avoid duplication of stuff that lives only in the .i file with %inline
:
%inline %{
typedef boost::shared_ptr< std::ofstream > ofstream_ptr;
ofstream_ptr mk_out(const std::string& fname ){
return ofstream_ptr( new std::ofstream( fname.c_str() ) );
}
%}
Which declares, defines and wraps it all in one shot.
这篇关于如何避免shared_ptr和SWIG的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!