3

これは簡単な手順のはずですが、まだ数日間私を逃しています.

私の状況は次のとおりです。

比較的単純な C++ インターフェイスを SWIG でラップしているので、Python で使用できます。ただし、メソッドの 1 つがカスタム構造体を返すという事実により、問題は複雑になります。その定義は次のとおりです。

struct DashNetMsg {
  uint64_t timestamp;
    char type[64];
    char message[1024];
};

これを実現するための SWIG インターフェイス ファイルを次に示します。

%module DashboardClient
%{
#include "aos/atom_code/dashboard/DashNetMsg.h"
#include "DashboardClient.h"
%}

%import "aos/atom_code/dashboard/DashNetMsg.h"
%include "DashboardClient.h"

%ignore Recv(DashNetMsg *);

"DashboardClient.h" と "DashboardClient.cpp" は、クラス "DashboardClient" とそのメソッドを宣言および定義します。これをラップしています。「DashNetMsg.h」は、文字通り上記の構造体定義だけを含むヘッダー ファイルです。以下は、DashboadClient.cpp からの DashboardClient.Recv メソッドの定義です。

DashNetMsg DashboardClient::Recv() {
  DashNetMsg ret;
  if (Recv(&ret)) {
    // Indicate a null message
    strcpy(ret.type, "NullMessage");
  }

  return ret;
}

これをコンパイルしてPythonにロードすると、2つの興味深い(私が思うに)相互に関連する問題が発生します。

Python 3.1.3 (r313:86834, Nov 28 2010, 10:01:07) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import DashboardClient
>>> d = DashboardClient.DashboardClient()
>>> m = d.Recv()
>>> m
<Swig Object of type 'DashNetMsg *' at 0x7f4d4fc2d3c0>
>>> m.type
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'SwigPyObject' object has no attribute 'type'
>>> exit()
swig/python detected a memory leak of type 'DashNetMsg *', no destructor found.

まず、DashNetMsg は明らかに「タイプ」と呼ばれる属性を定義します。次に、このメモリ リークの原因は何ですか? SWIGによると:

インターフェイスで何も定義されていない場合、SWIG はデフォルトのコンストラクタとデストラクタ関数を作成します。

( http://www.swig.org/Doc2.0/SWIG.html、セクション 5.5)

このラップされた型のデストラクタを作成する必要があるということではありませんか? また、構造体の属性にアクセスできないのはなぜですか?

うまくいかなかった解決策

何が起こっているのかを説明できる私の最善の推測は、何らかの理由で SWIG が実際には DashNetMsg 構造体をラップしておらず、代わりにそれを不透明なポインターとして扱っているということです。SWIG は、これらのポインターが指すものを手動で解放する必要があることを示しているように見えるため、メモリ リークも説明できると思います。しかし、たとえそうだとしても、SWIG が構造体をラップしない理由がわかりません。

ここで、swig を認識するには C スタイルで宣言された構造体が必要であると読みました。したがって、私はこれを試しました:

typedef struct DashNetMsg {
  uint64_t timestamp;
    char type[64];
    char message[1024];
} DashNetMsg;

上記と全く同じ結果でした。

4

1 に答える 1

1

SWIG で s を値で返すstructのはトリッキーです。ドキュメントから

値によって構造体またはクラスのデータ型を返す C 関数は、処理がより困難です...SWIG は実際にはポインターのみをサポートします。

SWIG は新しいオブジェクトを割り当て、それへの参照を返します。返されたオブジェクトが使用されなくなった場合、それを削除するのはユーザーの責任です。暗黙的なメモリ割り当てを認識せず、結果を解放するための手順を実行しないと、メモリ リークが発生することは明らかです。

于 2013-09-11T03:10:29.783 に答える