Lebensdauer von temporären Objekten in SWIG Python Wrappern (?)

8

Bearbeitet am 12. Februar

Ich habe gerade einen seltsamen Absturz mit einigen SWIG-generierten Python-Wrappern für einige C ++ - Klassen gemacht. Es scheint, dass die Kombination von SWIG und Python etwas daran interessiert ist, temporäre Werte zu bereinigen. So begierig, dass sie aufgeräumt werden, solange sie noch benutzt werden. Eine deutlich verkürzte Version sieht so aus:

%Vor%

Ich starte SWIG (1.3.37) in der .i-Datei und dann in Python:

%Vor%

Es scheint, dass in der zweiten Instanz das temporäre Objekt Bar zerstört wird, bevor wir% c_de%% s theFoo -Feld lesen können. Dinge in gdb herumjagen, das ist eindeutig was passiert. Und zu dem Zeitpunkt, als wir value von .value gelesen haben, hat C ++ bereits Bar().theFoo zerstört (und mit einer anderen Heap-Zuweisung überschrieben). In meiner aktuellen Situation verursacht dies einen segfault.

Gibt es eine SWIG-Anweisung oder einen Trick, den ich meiner .theFoo -Datei hinzufügen kann, um Example.i return Bar().theFoo.value hier zu machen?

    
Managu 12.02.2011, 00:45
quelle

1 Antwort

2

Zweites Update :

Nun, wir wissen, dass das grundlegende Problem ist, dass Python Bar sofort zerstört. Wenn Bar in Python implementiert ist, weiß Python's gc, dass es immer noch einen Verweis auf theFoo gibt, und zerstört es nicht. Aber wenn Bar in C ++ implementiert ist, ruft python den C ++ - Destruktor auf, der automatisch theFoo zusammen mit Bar.

zerstört

Die offensichtliche Lösung besteht also darin, zu verhindern, dass Python Bar vorzeitig zerstört. Hier ist eine leicht hackische Lösung mit Unterklassen Bar :

%Vor%

Dies speichert einen Verweis auf die letzte Bar erstellt, so dass es nicht sofort zerstört wird. Wenn ein neues Bar erstellt wird, wird das alte gelöscht. (Meine alte Version war albern; keine Notwendigkeit, __del__ dafür zu überschreiben.) Hier ist die Ausgabe (mit cout << "deleting Foo " in Foo destructor):

%Vor%

Ich liebe das immer noch nicht. Es könnte besser sein, das "persistente" Verhalten in einem Decorator zu maskieren; Ich habe das auch versucht und es hat funktioniert (wenn Sie den Code sehen wollen, lassen Sie es mich wissen). Es wäre definitiv besser, python irgendwie zu sagen, dass er sich damit beschäftigt, theFoo selbst zu zerstören, aber ich kann mir nicht vorstellen, wie das geht.

Erstes Update :

Der Umbruchcode sagte mir nichts, also schaute ich in swigexample.py. Das hat auch nichts ergeben. Dinge wurden klarer, als ich versuchte, Bar in reinem Python zu duplizieren:

%Vor%

Jetzt importieren wir Bar aus pyfoobar:

%Vor%

Dieses Verhalten kommt von Python!

Ursprüngliche Antwort :

Es scheint, als gäbe es hier auf jeden Fall einige Garbage-Collection-Kämpfe ... Hier einige Informationen zu SWIG Speicherverwaltung Auf dieser Grundlage sieht es so aus, als ob die Anweisung% newobject das ist, wonach Sie suchen. aber ich habe verschiedene Varianten ausprobiert und konnte es nicht dazu bringen, python über theFoo zu steuern:

%Vor%

Ich fange an zu vermuten, dass dies beabsichtigt ist; scheint wie diese Linie von dem obigen Link relevant ist:

  

C hält jetzt einen Hinweis auf die   Objekt --- Sie wahrscheinlich nicht wollen   Python, um es zu zerstören.

Aber ich bin mir nicht sicher. Ich schaue mir den swigexample_wrap-Code an, um zu sehen, ob ich herausfinden kann, ob ~Bar aufgerufen wird.

    
senderle 12.02.2011 03:53
quelle