Frage

Ich habe zwei verschiedene Python-Erweiterungsmodule bekommt; nennen wir sie A und B Modul A enthält einen Speicherklasse Typ Container genannt, dass ich innerhalb von Modul B als Rückgabetyp einer Klassenmethode verwendet werden soll.

Ich kann keine Dokumentation zu finden scheinen, wie ich soll, dies zu tun. Ich folgte in etwa diesem Artikel werden die Module / Klassen zu erstellen, außer ich nicht alle Methoden als statisch deklarieren haben, so würden sie zugänglich sein: http://nedbatchelder.com/text/whirlext.html

Meine Frage ist dann, wie gehe ich über eine Instanz des Behälters zu schaffen, dass ich als PyObject * Rückgabewert einer Klassenmethode in Modul B passieren zurück kann? Die Container-Definition sieht wie folgt aus:

typedef struct {
    PyObject_HEAD

    storageclass* cnt_;
} container;

Ich habe versucht, einfach zu tun, dass sie innerhalb der Methode in Frage, wo container_init ist die Methode, die ich als tp_init für die Container-Klasse registriert haben:

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

Jedoch nach dem Python-Interpreter mir die Klasse immer wieder, dass ich die Methode aufgerufen. (D.h. myclassinstance.mymethod () zurückkehrt myclassinstance).

Ich werde dies offensichtlich über die falsche Art und Weise, aber ich habe keine Ahnung, was der richtige Weg ist. Irgendwelche Vorschläge? Nur um zu schneiden jemand aus, das wird es vorschlagen - kein bin ich nicht in mit SWIG oder Boost-interessiert :: Python. Ich habe versucht, dass bereits und die darunter liegende Speicherklasse für Container nicht spielte gut mit entweder (SWIG kann es nicht einmal analysieren). Bisher die Erweiterungen tun mir ziemlich schmerzlos gewesen, aber ich bin auf dieser stumped.

War es hilfreich?

Lösung

Ihr Problem ist, dass type->tp_init nicht tut, was Sie wollen. type->tp_init wird aufgerufen, nachdem ein Objekt zugeordnet ist, die Instanziierung zu tun. Sie würden zunächst das Objekt mit type->tp_new zuweisen müssen, übergeben Sie dann das Objekt als erstes Argument zu type->tp_init. Da Sie eine nicht initialisierte Zeiger auf tp_init passieren, sind alle Wetten ab. Sie rufen typischerweise nicht so oder Funktion direkt, aber, und anstelle eines PyObject_Call*() auf dem Typ Objekt aufrufen selbst eine neue Instanz zu erstellen. Oder bietet eine normale C-Funktion eine neue Instanz, a la PyFoo_New() zu erstellen.

sagte, dass die übliche Art und Weise Kommunikation zwischen zwei Erweiterungsmodulen zu tun, ist es durch das Python-API zu tun. Wenn Sie das Modul B auf Import und Verwendung Modul A wollen, rufen Sie PyImport_Import() das Modul-Objekt zu erhalten, PyObject_GetAttrString() den Typ-Objekt zu erhalten, die Sie interessieren, und einer von PyObject_Call*() es zu instanziiert. Jeder Ort, den Sie einen Zeiger auf diese Art speichern möchten, müssen Sie nur eine PyObject * nehmen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top