如何使用shared_ptr和SWIG避免内存泄漏 - c++

我正在尝试使用boost::shared_ptr允许我在python脚本中使用c ++文件I / O流对象。但是,生成的包装器警告我它正在泄漏内存。

这是一个显示问题的最小.i文件:

%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')


%}

这是警告:

In [2]: ptrtest.leak_memory()
swig/python detected a memory leak of type 'ofstream_ptr *', no destructor found.

有没有一种方法可以修改.i文件,以告诉接口如何正确处理shared_ptr?

参考方案

您的示例缺少两部分来运行析构函数:

  • 由于SWIG对std::ofstream完全一无所知,因此默认行为是除了传递不透明的句柄之外,什么也不做。有关此内容的进一步讨论,请参见another answer of mine。
    此处的解决方法是在接口文件中为std::ofstream提供一个空定义,以说服SWIG即使您不打算公开任何成员,它也知道可以做更多的事情。
  • SWIG需要查看typedef本身-在%{ %}内部,它只是直接传递给输出模块,而在包装自身中未使用。
  • 因此,您的示例变为:

    %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')
    %}
    

    为了将来参考,您可以避免重复使用%inline的仅存在于.i文件中的内容:

    %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() ) );
    }
    %}
    

    声明,定义和包装所有内容。

    在Java中,执行“ ++++++++”表达式,编译器未报告任何错误并且可以正确执行? - java

    我用eclipse编写了这段代码,用war写过,结果为3d。public static void main(String[] args) { double a = 5d + + + + + +-+3d; System.out.println(a); } 参考方案 您的表情可以改写为(5d) + (+ + + + +-+3d) 其中第一个+是应用于两个操作数的…

    将Python嵌入C++应用程序 - c++

    上下文:我们一直面临的一个持续问题是对我们的市场数据应用程序进行单元测试。这些应用程序坐下来观察从提要中检索到的数据并执行某些操作。一些很难触发的关键事件很少发生,并且测试人员很难在所有情况下验证我们的应用程序是否正常运行,因此我们必须依靠单元测试。这些系统通常通过在事件发生时发出回调(进入我们的应用程序)来工作,然后由我们负责处理此事件。 我设想的解决方案…

    Python的C++名称处理库 - c++

    Improve this question 我想在Python程序中修改和分解C++函数名。有没有类似的东西可用?我搜索了几个小时,也许我很幸运在这里... 参考方案 您很可能不想在Python中执行此操作。顺便说一句,您可能不应该从DLL中导出错误的名称,因为这样会使具有不同编译器的人难以使用。如果必须使用变形的名称,则只需在Python代码中对其进行硬编…

    用于Python和C++应用程序的简单但快速的IPC方法? - c++

    我有一个同时使用Python和C++代码的GNU Radio应用程序。我希望能够表示事件的C++代码。如果它们在同一范围内,我通常会使用一个简单的布尔值,但是代码是分开的,因此需要某种形式的共享内存。有问题的代码对性能至关重要,因此需要一种有效的方法。我最初考虑的是可由Python和C++访问的共享内存段。因此,我可以在python代码中设置一个标志,并从C…

    扩展Python时可以使用C++功能吗? - c++

    Python手册说您可以在C和C++中为Python创建模块。使用C++时可以利用类和模板之类的东西吗?它不会与其他库和解释器产生不兼容吗? 参考方案 挂钩函数的实现是用C还是用C++实现都没有关系。实际上,我已经看过一些Python扩展,这些扩展有效利用C++模板甚至Boost库。没问题。 :-)