2011-08-01 12 views
10

EventManagerクラスはC++で書かれており、Pythonに公開されています。これは、Pythonの側から使用するために、私が意図する方法である:Boost.Python:クラス関数へのコールバック

class Something: 
    def __init__(self): 
     EventManager.addEventHandler(FooEvent, self.onFooEvent) 
    def __del__(self): 
     EventManager.removeEventHandler(FooEvent, self.onFooEvent) 
    def onFooEvent(self, event): 
     pass 

add-remove-EventManagerの静的関数として公開されている。)

上記のコードに問題がコールバックすることですboost::python::objectインスタンス内に取り込まれます。私がself.onFooEventを実行すると、参照カウントがselfに増加し、削除されないので、デストラクタが呼び出されないので、イベントハンドラは決して削除されません(アプリケーションの最後を除いて)。

このコードは、self引数を持たない関数(つまり、フリー関数または静的関数)ではうまく機能します。参照カウントを増やさないように、Python関数オブジェクトをどのようにキャプチャする必要がありますか?私はオブジェクトに弱い参照が必要です。

+0

とにかく '__del__'に頼るべきではありません。代わりに、定期的なメソッドを公開してイベントハンドラを削除します。 (おそらく、 'x = Something(); use(x);#のようなコードがあれば、[コンテキストマネージャ](http://docs.python.org/library/stdtypes.html#context-manager-types) xはこの時点から未使用でなければならない ') – delnan

+0

@delnanしかし、' Something'に似たクラスのオブジェクトは、別のC++マネージャに渡されます。そのマネージャはもはやそれらを必要としなくなると、それを削除します。私はこのコンテキストマネージャーでコンテキストマネージャーを使うことはできないと思う。 –

+0

ああ、コンテキストマネージャの提案を無視してください。それでも、(またはむしろ)削除する代わりに、イベントハンドラを削除するように伝えるだけでよいのです。そうしないと、メモリ管理をよりスマートにする次のパッチがコードリークを引き起こす可能性があります。 – delnan

答えて

0

weakref.ref(self.onFooEvent)を使用しないと、期待した動作が得られません。私のコメントを参照してください。

関連する問題