8

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 を適切に破棄する方法をインターフェイスに伝える方法はありますか?

4

1 に答える 1

9

あなたの例には、デストラクタを実行するための 2 つの部分がありません。

  1. SWIGstd::ofstreamは、不透明なハンドルを渡す以外に何もしないというデフォルトの動作についてまったく何も知らないためです。これについてのさらなる議論については、私の別の回答を参照してください。

    ここでの修正はstd::ofstream、たとえメンバーを公開する予定がない場合でも、SWIG がさらに多くのことを実行できることを認識できるように、インターフェース ファイルに空の定義を提供することです。

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

将来の参照のために、.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() ) );
}
%}

ワンショットですべてを宣言、定義、ラップします。

于 2013-09-19T20:25:57.830 に答える