Hello everybody,

We're using Boost.Python to embed an interpreter for our application.
We're having trouble with some code that I reduced to the following:

--------------------------------------------------------------------

#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/python.hpp>

#include <iostream>

using namespace boost;
using namespace boost::python;

template <typename T>
bool are_equal_using_less(const T& x, const T& y)
{
        return (!(x < y)) && (!(y < x));
}

template <class T>
void hold_python(shared_ptr<T>& x)
{
        x = extract<shared_ptr<T> >(object(x));
}

class A : public enable_shared_from_this<A>
{
public:
        shared_ptr<A> get_shared_from_this()
        {
                return shared_from_this();
        }
};

int main()
{
        Py_Initialize();

        class_<A, shared_ptr<A> >("A")
                .def("get_shared_from_this", &A::get_shared_from_this)
        ;

        shared_ptr<A> a(new A);
        shared_ptr<A> first_shared_from_this = a->get_shared_from_this();

        if (are_equal_using_less(first_shared_from_this, a))
                std::cout << "first_shared_from_this is equal to a - OK" << 
std::endl;
        else
                std::cout << "first_shared_from_this is NOT equal to a - BUG" 
<< std::endl;

        hold_python(a);

        if (are_equal_using_less(first_shared_from_this, a))
                std::cout << "first_shared_from_this is still equal to a" << 
std::endl;
        else
                std::cout << "now first_shared_from_this is not equal to a 
since a
was changed by hold_python - OK I think" << std::endl;

        shared_ptr<A> second_shared_from_this = a->get_shared_from_this();
        if (are_equal_using_less(second_shared_from_this, a))
                std::cout << "second_shared_from_this - OK" << std::endl;
        else
                std::cout << "we just called shared_from_this on a but we get 
back a
shared_ptr object that is not equal to a - isn't this a BUG?" <<
std::endl;

        return 0;
}

--------------------------------------------------------------------

In both 1.39.0 and 1.40.0 the result is:
first_shared_from_this is equal to a - OK
now first_shared_from_this is not equal to a since a was changed by
hold_python - OK I think
we just called shared_from_this on a but we get back a shared_ptr
object that is not equal to a - isn't this a BUG?

While in 1.34.0 we get:
first_shared_from_this is equal to a - OK
now first_shared_from_this is not equal to a since a was changed by
hold_python - OK I think
second_shared_from_this - OK

It probably doesn't matter but this is on Windows, with Visual Studio
2005 and Python 2.4.

The hold_python function in the code above comes from combining ideas
in 2 older threads on this list.
At http://mail.python.org/pipermail/cplusplus-sig/2006-January/009671.html
my colleague asks how to get a reference to the same Python object
rather than having Boost.Python always create a new wrapper (if you
read the discussion above notice that it is unfortunately split in 2
threads). One of the answers references a message by David Abrahams
here http://mail.python.org/pipermail/cplusplus-sig/2005-April/008537.html.
So my colleague chose to call hold_python after the allocation of the
object, just like shared_ptr a(new A); hold_python(a) in the example
above. This worked for us until upgrading from 1.34 to 1.39.

It could very well be that the problem is on our side not in Boost but
given that Boost.Python is quite esoteric any help from somebody who
has more insight into it is very valuable.

Thank you,
Catalin
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to