[prev in list] [next in list] [prev in thread] [next in thread] 

List:       python-cpp-sig
Subject:    Re: [C++-sig] copy constructors and multiple instances
From:       Josh Stratton <strattonbrazil () gmail ! com>
Date:       2011-09-01 20:01:52
Message-ID: CAPVmgLjvzUxs9g8QtGDxYPfsBJRemVzpkMcsjf-yzw=xVE_Ukw () mail ! gmail ! com
[Download RAW message or body]

>> In my particular scene I have a Scene class, which operates as kind of
>> a context for my operations and holds all the meshes in the scene.  I
>> send my scene down to the python side so import methods will import
>> into the containers in the scene object.  For example,
>> addMeshFromFile(scene, fileName) which puts the data from the file
>> into the scene object.  However, if the scene object isn't be
>> returned, it seems I'm just copying the scene object (which might be
>> memory expensive), adding the data to the copy, and throwing the copy
>> away as I don't return it and it doesn't affect my original scene
>> object in C++ that I passed in.  I assume this is a fairly common
>> problem and I need to rework my API somehow like providing a more
>> robust copy constructor that does a shallow copy of my data
>> containers.  Still, I might have to reorganize it so I'm not passing
>> my scene to python.  If an object is copied every time, I think that
>> might be memory prohibitive.  I'm including my current source from
>> github.
>>
>> // header file handling my scene and it's data
>> https://github.com/strattonbrazil/Sunshine/blob/master/src/scene.h
>>
>> // functions for creating the bindings to python
>>
>> https://github.com/strattonbrazil/Sunshine/blob/master/src/python_bindings.cpp
>>
>> // python file which reads a file and adds it to the scene
>> https://github.com/strattonbrazil/Sunshine/blob/master/src/objImporter.py
>>
>> Do I need to change need to change my copy constructor to do a more
>> shallow copy?  Maybe change my internal scene objects to pointers?
>> Would this alleviate the memory issue?
>
> A couple of comments:
>
> - 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"?

> - 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.

> - If you really want to ensure Boost.Python doesn't make unnecessary copies
> of Scene, wrap it with:
>
> class_<Scene,QSharedPointer<Scene>,boost::noncopyable>(...)
>
> That will cause things that require copies to produce compiler errors, and
> you can follow those errors to see exactly where the copy is required.  It
> will also keep you from returning Scene objects by value, however, but it
> sounds like that might be desirable.

I saw this in the docs and seems to be what I need.  Like you said, at
least I'd get compiling error instead of guessing what is going on in
the background.  Thanks.
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic