[C++-sig] copy constructors and multiple instances

Dave Abrahams dave at boostpro.com
Sat Sep 3 06:08:40 CEST 2011


on Fri Sep 02 2011, Josh Stratton <strattonbrazil-AT-gmail.com> wrote:

> Here's a really short example of what I don't understand.  Basically I
> can setup the python function to accept shared pointers, but can I
> setup it to also use normal pointers?  

Yes, once you've exposed the class to Python, you can pass pointers to
Python.  However, Boost.Python won't let you pass raw pointers around
without telling it (via call policies) what you want to do about
lifetime management... actually what it will do, if you don't tell it
otherwise, is copy the pointee, which is at least safe from an object
lifetime point-of-view.

> In the example code attached, if I uncomment
> scene->sendYourselfToPython(); it fails because it's using "this" as
> the scene pointer.

(It's already uncommented)

> Error in Python: <type 'exceptions.TypeError'>: No to_python
> (by-value) converter found for C++ type: Scene

...because you've said it's noncopyable, there's no way to copy the
pointee, which is what happens when it is passed by value.

> So it appears to only work for shared pointers at this point.  Can I
> also get it to work with "this" at the same time?  Jim pointed me to
> "enable_shared_from_this" as a way for creating a shared pointer
> object, which makes sense from the docs of how to do it, but I was
> wondering if I necessarily NEED to send it down as a shared pointer.

There *are* things you can do to subvert Python's checking, but they're
highly discouraged.  Jim is on the right track: if you want to pass a
mutable reference to the object and you want its lifetime to be properly
managed, you should do what he's saying.  If you don't like
using enable_shared_from_this, of course, you can just do it outside a
member function:

  void sendSceneToPython(SceneP s)
    try {
      object ignored = exec(EXAMPLE_PY_FUNCTION, pyMainNamespace);
      object processFileFunc = pyMainModule.attr("Foo").attr("processFile");
      processFileFunc(s, "test.txt");
    } catch (boost::python::error_already_set const &) {
      std::string perror = parse_python_exception();
      std::cerr << "Error in Python: " << perror << std::endl;
    }
  }

HTH,

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com



More information about the Cplusplus-sig mailing list