Lifetime of temporary objects in SWIG's Python wrappers (?)

Edited 12 Feb

I've just recently come up with an odd crash using some SWIG-generated Python wrappers for some C++ classes. It seems that the combination of SWIG and Python together are somewhat eager to clean up temporary values. So eager, in fact, that they're cleaned up while they're still being used. A significantly condensed version looks like this:

/* Example.hpp */
struct Foo {
    int value;
    ~Foo();
};

struct Bar {
    Foo theFoo;
    Bar();
};

/* Example.cpp */
#include "Example.hpp"
Bar::Bar()  {theFoo.value=1;}
Foo::~Foo() {value=0;}

/* Example.i */
%module Example
%{
#include "Example.hpp"
%}
%include "Example.hpp"

I run SWIG (1.3.37) on the .i file, and then in Python, have:

Python 2.4.3 (#1, Sept 17 2008, 16:07:08)
[GCC 4.1.2 20071124 (Red Hat 4.1.2-41)] on linux2
Type "help", "copyright", "credits", or "license" for more information.
>>> from Example import Bar
>>> b=Bar()
>>> print b.theFoo.value      # expect '1', since Bar's constructor sets this
1
>>> print Bar().theFoo.value  # expect '1', since we're still using the Foo object
26403424

It seems that in the second instance, the temporary Bar object is destroyed before we ever get to read theFoo's value field. Chasing things around in gdb, this is clearly what's happening. And so by the time we read .value from Bar().theFoo, C++ has already destroyed (and overwritten with some other heap allocation) .theFoo. In my actual situation, this is causing a segfault.

Is there any SWIG directive or trick that I can add to my Example.i file to make Bar().theFoo.value return 1 here?

8
задан Managu 12 February 2011 в 19:53
поделиться