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

Josh Stratton strattonbrazil at gmail.com
Fri Sep 2 04:31:24 CEST 2011


BOOST_PYTHON_MODULE(scene)
{
    class_<Scene, boost::noncopyable>("Scene");
}

// later calling this
boost::python::register_ptr_to_python< boost::shared_ptr<Scene> >();
PyImport_AppendInittab("scene", &initscene);

So is this all I really need for the mapping then?  I'm getting an
error trying to send the Scene object down to python.

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

On Thu, Sep 1, 2011 at 1:52 PM, Jim Bosch <talljimbo at gmail.com> wrote:
> 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