Wie erkenne ich ob ein Objekt lebt?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
DonnerCobra
User
Beiträge: 53
Registriert: Mittwoch 9. April 2008, 19:35

Hi!

Ich habe ein großes Problem mit meinem eingebetteten Python Interpreter. Meine Anbindung ist ein Plugin zu einem schon bestehenden Programm, das heißt ich kann einige Sachen nicht beeinflussen (das markiere ich mit einem *).

Stellt euch vor ich habe eine grafische Liste mit Objekten. Also einen Würfel, dann Kugel, usw.

Jetzt habe ich eine SandBox mit der ich nebenbei Python Code ausführen kann, und zwar:

obj = meineliste.first()

Jetzt wird das erste Element der Liste in eine Referenz gespeichert. Jetzt lösche ich per Hand das Objekt aus der Liste* (halt mit der Maus). Und jetzt gehe ich zurück in die Konsole und gebe folgendes ein:

print obj.get_name()

*crash*

Denn das Objekt wurde ja von dem Hauptprogramm gelöscht und ich kann leider nicht immer alles abfangen was gelöscht wurde. Das heißt, mein PyObject struct hat einen Pointer auf eine freigegebene Stelle und das crasht dann natürlich.

Hat einer eine Idee was ich machen kann um dem zu entgehen das es crasht? Ich würde gerne halt in allen Python Scopes alle Referenzen zu dem gerade gelöschten Objekt auf PyNone setzen.

Meine Idee:
Kann man in C++ eventuell eine freigegebene Stelle erkennen? Dann könnt eich das vorher mit einer if anweisung abfangen.
Ich danke euch, bye :)
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hoi,

ich verstehe gerade nicht 100%ig, was Du beeinflussen kannst und was nicht. Also Pythonlisten haben keine .first()-Methode. Wenn Du das in C(++) implementiert hast, dürfte es schwierig sein, für die Liste sich zu erinnern, an welche Objekte Pointer übergeben wurden. (Klar geht das, aber nur mit Aufwand).

Vielleicht ist eine Lösung keinen Pointer zu übergeben, sondern das Objekt an sich? Dazu müsstest Du es natürlich duplizieren.

Ich weiß nicht was "meineliste" sonst noch so können muß, aber sonst kannst Du auch einfach eine Pythonliste nehmen. Die hat zwar keine .first()-Methode, aber

Code: Alles auswählen

obj = meineliste[0]
tut's auch.

HTH
Christian
DonnerCobra
User
Beiträge: 53
Registriert: Mittwoch 9. April 2008, 19:35

Hi!

Sorry, das habe ich dann wohl nicht richtig erklärt.

meineliste ist keine Python Liste sondern eine gewrappte C++ Klasse die die methode "first()" besitzt.

Folgendes Beispiel

meineliste.first().get_point[40].x = 300

Das erste "PolygonObjekt" der Liste wird zurückgegeben und der 40. Punkt, dessen x wert wird auf 300 gesetzt.

Demnach ist das eine direkte Referenz auf das Objekt in der Liste und deswegen enthält das PyObject dann auch einen Pointer und nicht das ganze Objekt.

Und genau hier ist jetzt das Problem. Wenn ich das erste Objekt in eine seperate Referenz schreibe, hat die neue Referenz automatisch die Adresse des ersten Objektes, auch wenn es danach nicht mehr das erste Objekt ist. Lösche ich das Objekt dann in der grafischen Liste,
crasht es, weil der Pointer weiterhin vorhanden ist.

Danke :)
BlackJack

Pech gehabt würde ich sagen. Du kannst auf jeden Fall nicht mit vertretbarem Aufwand alle Namen und Referenzen zu dem Objekt auf der Python-Seite durch `None` ersetzen, selbst wenn Du irgend wie mitbekommen könntest, dass das C++-Objekt zerstört wurde.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Möchte mich BJ anschließen: Pech gehabt. Aber das ist irgendwo ein Designfehler. Und wenn Du die C++-Klasse unter Kontrolle hast (es Dein Code ist), kannst Du es entsprechend umstricken.

Jetzt wissen wir nicht wie Du den gewrapped hast, aber wenn das Pythonobject Pointer auf andere (C++-Objekte) enthält (wie Du schreibst) - und das per se -, dann ist das eine ungünstige Konstellation.

Gruß,
Christian
DonnerCobra
User
Beiträge: 53
Registriert: Mittwoch 9. April 2008, 19:35

Gibt es in C++ keine Möglichkeit eine Speicherstelle darauf zu prüfen, ob sie freigebene ist, oder nicht?

Bye :)
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

DonnerCobra hat geschrieben:Gibt es in C++ keine Möglichkeit eine Speicherstelle darauf zu prüfen, ob sie freigebene ist, oder nicht?
Was heißt das?
- Allgemein? Kaum, es sei denn über einen zweiten "Buchhaltungscontainer", oder durch explizites "ausNULLen" und Test darauf.
- STL-Container? Die mußt Du schon überlisten, um Lücken zu erzeugen.
- was Anderes?

edit: PS: Ich ging davon aus, dass es hier um diese "list like objects" geht, die wir eben eigentlich nicht kennen.
DonnerCobra
User
Beiträge: 53
Registriert: Mittwoch 9. April 2008, 19:35

Hi!

Also das hier ist mein PyObject:

typedef struct {
PyObject_HEAD
MyObject* obj;
Py_ssize_t wrap;
} csMyObject;


Py_ssize_t enthält einen 1 oder 0 Wert. Je nachdem ob der Besitz des Objektes MyObject* an das Hauptprogramm abgegeben wurde, oder ob das Objekt beim deallokieren des PyObjektes gelöscht werden soll.

Aber das ist nicht die Sache. Bei "obj = mylist.first()"
wird in *obj der Pointer zu dem ersten Objekt der Liste geliefert. Wenn ich es jetzt an die zweite Stelle verschiebe, ist obj natürlich immernoch genau darauf gelinkt.

Wenn ich das Objekt außerhalb von Python, also im Programm ganz aus der Liste lösche, dann zeigt obj natürlich noch auf das Objekt im Speicher, welches natürlich schon längst weg ist.


Bye! Ich hoffe ich konnte euch das jetzt so nahe bringen.. Sorry für die bisher schlechte Erklärung.
lunar

In der Liste shared pointer nutzen, und die Python-Referenz über weak pointer zugreifen lassen.

Wenn du den shared pointer in der Liste dann mit delete löscht, wird das Objekt gelöscht, und der Zugriff über den weak pointer in der Referenz schlägt kontrolliert fehl, so dass du z.B. eine Ausnahme werfen kannst.
DonnerCobra
User
Beiträge: 53
Registriert: Mittwoch 9. April 2008, 19:35

Hi!

@lunar: Das geht leider nicht so ganz. Ich habe keinen Zugriff auf die Liste, weil sie gekapselt, also geschützt ist nach aussen hin.
lunar

Tja, dann kann ich mich auch nur BlackJack und CM anschließen. Ein Zeiger kennt keinen Zustand "belegt" oder "freigegeben", eine Zeiger zeigt halt auf eine Speicherstelle. Und wenn da nichts mehr ist, gibts halt segfaults oder ähnliches.

Gerade um das zu vermeiden, wurden shared pointer ja erfunden.
DonnerCobra
User
Beiträge: 53
Registriert: Mittwoch 9. April 2008, 19:35

Hi!

Okay, danke sehr für deine Hilfe.
Antworten