[C++-sig] copy constructors and multiple instances
Jim Bosch
talljimbo at gmail.com
Thu Sep 1 22:52:56 CEST 2011
On 09/01/2011 01:01 PM, Josh Stratton wrote:
>> - I'm a bit confused by your python_bindings.cpp file; did you paste
>> together several files? If not, I've never seen anyone try to define more
>> than one module in a single shared library, and I don't it's supposed to
>> work. You can wrap all of your objects in a single Python module - the body
>> of a BOOST_PYTHON_MODULE block is just a regular function block, so you can
>> include as many calls to class_ (and other things) in there as you like.
>> This might be part of the confusion about needing to import modules from
>> one of your earlier emails.
>
> I'm currently just embedding python, but I eventually wanted to extend
> it down the road. I guess putting everything under the same macro
> makes more sense. One thing I could find briefly skimming over the
> docs is creating submodules. If the BOOST_PYTHON_MODULE is named
> "foo", is there some macro/function I can put inside of that handles
> submodules, so classes imported under it are imported in python such
> as "from foo.bar import SomeClass"?
>
To do that, you just need to add some pure Python and a directory
structure. If "foo" is a directory, and bar.so is a Boost.Python
extension module (suffix is different on Windows, of course), you just
need to have:
foo/__init__.py
foo/bar.so
But just like you can't have a pure-Python package+module structure in a
single file, you can't do it in C++ either; you need to have a directory
and the __init__.py file.
>> - You shouldn't have to do anything to the copy constructor to make this
>> work. Boost.Python is perfectly happy to pass things by reference or by
>> pointer. It could be that your QSharedPointers are getting in the way of
>> this. What is the signature of Mesh::buildByIndex? If the Scene is passed
>> by QSharedPointer, that might force a copy, because Boost.Python only knows
>> how to dereference the pointer, not copy it (in other words, it doesn't want
>> to assume it can copy the smart pointer, because some smart pointers like
>> auto_ptr can't be copied, so it's making a new QSharedPointer from a
>> copy-constructed object). If you can change it, just make it take a Scene
>> by reference - that will almost certainly avoid making copies. Alternately,
>> if you can use boost::shared_ptr instead, that will also solve all of your
>> problems. Unfortunately support for non-boost shared pointers isn't great
>> in Boost.Python right now.
>
> Switching to boost's shared_ptr shouldn't be difficult.
> Mesh::buildByIndex does take a shared-pointer, but if I understand
> correctly, switching to boost::shared_ptr<Scene> should solve my
> issue.
Yup. With boost::shared_ptr, you don't even need to include it as a
template argument of class_, if you instead add the line:
boost::python::register_ptr_to_python< boost::shared_ptr<Scene> >();
This allows you to return shared_ptr to Python, but because a
boost::shared_ptr can use an arbitrary deleter, Boost.Python can convert
any wrapped Scene object (even one that doesn't hold a
shared_ptr<Scene>) into a shared_ptr<Scene> with correct reference counting.
If you do include boost::shared_ptr<Scene> in the class_ template
arguments, all Scene objects constructed in Python will be inside a
shared_ptr, but because of the above, that isn't necessary unless you
have functions that need to reset the shared_ptr itself.
Jim
More information about the Cplusplus-sig
mailing list