2011-08-01 27 views
10

Tengo una clase EventManager escrita en C++ y expuesta a Python. Esta es la forma I, destinados a que sea utilizado por la banda de Python: (. El add- y remove- se exponen como funciones estáticas de EventManager)Boost.Python: Devolución de llamada a funciones de clase

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

El problema con el código anterior es que las devoluciones de llamada se capturan dentro de las instancias boost::python::object; cuando hago self.onFooEvent, esto aumentará el recuento de referencia de self, lo que evitará que se elimine, por lo que nunca se llama al destructor, por lo que los controladores de eventos nunca se eliminan (excepto al final de la aplicación).

El código funciona bien para las funciones que no tienen un argumento self (es decir, funciones libres o estáticas). ¿Cómo debo capturar los objetos de función de Python de modo que no aumente su recuento de referencias? Solo necesito una referencia débil a los objetos.

+0

No debe confiar en '__del__' de todos modos. En su lugar, exponga un método regular para eliminar el controlador de eventos. (Tal vez conviértalo en [gestor de contexto] (http://docs.python.org/library/stdtypes.html#context-manager-types) si ve código como 'x = Something(); use (x); # x no se debe usar a partir de este momento ') – delnan

+0

@delnan Pero los objetos de clases similares a' Something 'se pasarán a otro administrador de C++. Cuando ese gerente ya no los necesita, los elimina. No creo que pueda usar gestores de contexto en este ... uhm, contexto. –

+0

Oh, no importa la sugerencia del administrador de contexto entonces. Aún así, en lugar de (o más bien, además de) eliminarlos, solo debe decirles que eliminen sus manejadores de eventos. De lo contrario, el siguiente parche para hacer que la administración de la memoria sea más inteligente podría hacer que se escape el código. – delnan

Respuesta

0

Sin weakref.ref (self.onFooEvent) nunca obtendrá el comportamiento esperado. Ver mi comentario

Cuestiones relacionadas