On 09/01/2011 07:03 AM, Josh Stratton wrote:
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.

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

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

Jim


_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to