Exposing std::vector using vector_indexing_suite
Hi, We have a simple data structure like this, that we would like to expose via boost python: struct Layer { double value; }; struct Document { std::vector< Layer > layer; }; If we were writing this in pure python, then it could be written as follows: class Layer: def __init__( self ): self.value = 0.0 class Document: def __init__( self ): self.layers = [] We would like our C++ bindings to match the behaviour of python as closely as possible. But we have encountered a scenario in which it doesn't, and we wanted to get some advice on the best way forward. In pure python, the following code produces an output of '123.0': l = Layer( ) d = Document( ) d.layers.append( l ) l.value = 123.0 print d.layers[0].value When exposing C++ classes via boost python (using the vector_indexing_suite for Document.layers), it produces a result of '0.0'. The 'append' is making a copy such that 'l' and 'd.layers[0]' are two separate objects. We've noticed that one way to make this work is by using shared_ptr in our C++ data structure, but we feel we would have to compromise on our C++ API as a result. Do we have any other options? Thanks, James.
On Nov 26, 2014 6:37 AM, "James Bird" <jsb@dneg.com> wrote:
Hi,
We have a simple data structure like this, that we would like to expose
via boost python:
struct Layer { double value; };
struct Document { std::vector< Layer > layer; };
If we were writing this in pure python, then it could be written as
follows:
class Layer: def __init__( self ): self.value = 0.0
class Document: def __init__( self ): self.layers = []
We would like our C++ bindings to match the behaviour of python as
closely as possible. But we have encountered a scenario in which it doesn't, and we wanted to get some advice on the best way forward.
In pure python, the following code produces an output of '123.0':
l = Layer( ) d = Document( ) d.layers.append( l ) l.value = 123.0 print d.layers[0].value
When exposing C++ classes via boost python (using the
vector_indexing_suite for Document.layers), it produces a result of '0.0'.
The 'append' is making a copy such that 'l' and 'd.layers[0]' are two
separate objects. We've noticed that one way to make this work is by using shared_ptr in our C++ data structure, but we feel we would have to compromise on our C++ API as a result. Do we have any other options?
I don't think you have any good ones. Any simple C++ version of your Python snippet would also deep-copy the Layer object; append() is copying here simply because it's calling std::vector::push_back(), and that's what the std::vector does. If you want this to work across the C++/Python boundary, you'll need to make it work in pure C++ first, and I do think using shared_ptr seems like the most natural way to do that. Jim
participants (2)
-
James Bird -
Jim Bosch