Boost logo

Boost :

Subject: Re: [boost] enable_shared_from_this2
From: Daniel F. (the.source_at_[hidden])
Date: 2010-03-07 19:30:08


I would also like to express my interest in a solution to the
enable_shared_from_this/python problem. In my opinion providing an
adequate solution would really benefit boost::python and I'm glad to see
work is being done. I've checked out the latest code from svn and played
around with it. I had to modify enable_shared_from_raw.hpp slightly in
order to get it to compile (mainly insert esft2_deleter_wrapper from the
old enable_shared_from_this2.hpp). Once it compiled I tested it in the
following scenario:

#include <iostream>
#include <string>

#define BOOST_ALL_DYN_LINK 1

#include <boost/smart_ptr/enable_shared_from_raw.hpp>
#include <boost/make_shared.hpp>
#include <boost/smart_ptr.hpp>

#include <boost/python.hpp>

namespace py = boost::python;

class Object: public boost::enable_shared_from_raw //public
boost::enable_shared_from_this<Object>
{
public:
     Object(const std::string& _name): name(_name) {
         std::cout << "Construct: " << name << std::endl;
     }
     ~Object() {
         std::cout << "Destruct: " << name << std::endl;
     }

     boost::shared_ptr<Object> shared()
     {
         boost::shared_ptr<Object> self =
boost::shared_from_raw<Object>(this); //shared_from_this();
         BOOST_ASSERT(self);
         return self;
     }
public:
     std::string name;
};

BOOST_PYTHON_MODULE(module)
{
     { //::Object
         typedef py::class_< Object > exposer_t;
         exposer_t exposer = exposer_t("Object", py::init<const
std::string&>());
         exposer.def_readwrite("name",&Object::name);
         exposer.def("shared",&Object::shared);
         py::register_ptr_to_python< boost::shared_ptr< Object > >();
     }
}

int main(int argc, char *argv[])
{
     int exit = EXIT_SUCCESS;

     Py_Initialize();

     try
     {
         initmodule();

         py::object main_module = py::import("__main__");
         py::object main_namespace = main_module.attr("__dict__");

         main_namespace["obj1"] = boost::make_shared<Object>("C++");

         py::exec(
             "import module\n"
             "print obj1.shared().name\n"
             "obj2 = module.Object('Python')\n"
             "print obj2.shared().name\n", // RuntimeError:
tr1::bad_weak_ptr
             main_namespace, main_namespace
         );

     }
     catch(const py::error_already_set&)
     {
         PyErr_Print();
         exit = EXIT_FAILURE;
     }

     Py_Finalize();

     return exit;
}

The results look good: the RuntimeError is gone, the objects are being
destroyed. Unfortunately, I only know little about the inner workings
smart pointers and even less about boost::python, so the before
mentioned code should be regarded with caution. So far, I've discovered
one case where this breaks, i.e. the following python code "obj2 =
obj2.shared()" causes the assertion in the destructor of
enable_shared_from_raw to fail. I'll assume that this is work in
progress (or really difficult to solve). Anyways, keep up the good work!

Berserker wrote:
> News about this problem?
> I just checked the latest svn revision and it seems that the code below
> doesn't work yet.
>
>
>
> Berserker wrote:
>> The expirity check seems working fine to me if merged in
>> enable_shared_ptr2 and solves some problems.
>> I can summarize other boost::python's problems in this example:
>>
>> class X : public boost::enable_shared_from_this2<X>
>> {
>> public:
>> void test()
>> {
>> shared_ptr<X> me = shared_from_this();
>> BOOST_ASSERT(me);
>> }
>> };
>>
>> void expose_x()
>> {
>> boost::python::class_<X>("X", boost::python::init<>()).
>> def("test", &X::test);
>> }
>>
>> ------------------------------------
>>
>> C++ case 1 (works fine):
>>
>> shared_ptr<X> x(new X);
>> x->test();
>>
>> ------------------------------------
>>
>> C++ case 2 (doesn't work because of the missing static/dynamic cast):
>>
>> X x;
>> x.test();
>>
>> ------------------------------------
>>
>> Python case (doesn't work, same problem of C++ case 2)
>>
>> x = X()
>> x.test()
>>
>> _______________________________________________
>> Unsubscribe & other changes:
>> http://lists.boost.org/mailman/listinfo.cgi/boost
>>
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk