Pregunta

Tengo dos módulos de extensión de Python diferentes; llamémoslos A y B. Un módulo contiene un tipo de clase de almacenamiento llamada contenedor que quiero usar dentro del módulo B como el tipo de retorno de un método de clase.

Me parece que no puede encontrar ninguna documentación sobre cómo se supone que debo hacer esto. He seguido más o menos este artículo para crear los módulos / clases, excepto que no declaró todos los métodos como estáticos, por lo que serían accesibles: http://nedbatchelder.com/text/whirlext.html

Mi pregunta es entonces, ¿cómo hago para crear una instancia del contenedor que pueda pasar de nuevo como el PyObject * valor de retorno de un método de clase en el módulo B? El aspecto de definición de contenedor como este:

typedef struct {
    PyObject_HEAD

    storageclass* cnt_;
} container;

He intentado simplemente haciendo lo siguiente en el método en cuestión, donde container_init es el método que se han inscrito como tp_init de la clase de contenedor:

pycnt::container* retval;
pycnt::container_init(retval, NULL, NULL);
return (PyObject*)retval;

Sin embargo, según el intérprete de Python que estoy volviendo a la clase que he llamado el método de. (Es decir, myclassinstance.mymethod () está regresando myclassinstance).

Obviamente estoy yendo de este por el camino equivocado, pero no tengo ni idea de lo que es la manera correcta. ¿Alguna sugerencia? Sólo para corte a nadie fuera que va a sugerir que - no, yo no estoy interesado en utilizar el TRAGO o Boost :: Python. He intentado ya y que la clase de almacenamiento subyacente para el envase no jugaba muy bien con (TRAGO ni siquiera podía analizarlo). Hasta ahora haciendo las extensiones mí ha sido bastante rápido, pero estoy perplejo en este caso.

¿Fue útil?

Solución

Su problema es que type->tp_init no hace lo que quiere. type->tp_init se llama después de un objeto se asigna a hacer la creación de instancias. En primer lugar, habría que asignar el objeto utilizando type->tp_new, a continuación, pasar a ese objeto como primer argumento a type->tp_init. Dado que se pasa un puntero no inicializado a tp_init, todas las apuestas están apagadas. Por lo general, no se llama a la función ya sea directamente, sin embargo, y en lugar de llamar a uno de PyObject_Call*() en el propio objeto de tipo para crear una nueva instancia. O proporcionar una función de C normal a crear una nueva instancia, a la PyFoo_New().

Dicho esto, la forma habitual de hacer intercomunicación entre dos módulos de extensión es hacerlo a través de la API de Python. Si desea que el módulo B al módulo de importación y el uso A, se llama a PyImport_Import() para obtener el objeto de módulo, PyObject_GetAttrString() para conseguir el objeto de texto que te interesa, y uno de PyObject_Call*() instanciarlo. En cualquier lugar que desee almacenar un puntero a su tipo, que acaba de tomar un PyObject *.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top