Exposing a C-style array data member to Python via Boost.Python
I have a struct that contains a C-style array data member. I'd like to have this struct exposed to Python, and this data member be accessible as a tuple in Python. struct S { char arr[10]; }; void foo( S const * ) {} BOOST_PYTHON_MODULE( test ) { using namespace boost::python; class_<S>( "S" ) .def_readwrite( "arr", &S::arr ) ; def( "foo", foo ); } The code above fails to build error C2440: '=' : cannot convert from 'const char [10]' to 'char [10]' C-style arrays are not assignable, so the error makes sense. The code compiles if I change the data member to a plain char instead of an array. I cannot replace the array with an std::array or some other container because the structure is being consumed by a C API. The only solution I can think of is to write a couple of wrappers and do the following 1. A struct S1 that duplicates S except it'll have an std::array instead of a C-style array 2. A foo_wrapper that accepts a S1 const *, copies the contents over to an S instance and calls foo 3. Register a to_python_converter to convert the std::array to a Python tuple This should work, and I'm not too concerned about the data copying at this point, but it'd be nice if I could avoid it and expose the array directly without having to jump through all these hoops. So the question is, how can I expose that C-style array data member to Python as a tuple?
Ashish Sadanandan <ashish.sadanandan <at> gmail.com> writes:
I have a struct that contains a C-style array data member. I'd like to have this struct exposed to Python, and this data member be accessible as a tuple in Python.
struct S { char arr[10]; };
So the question is, how can I expose that C-style array data member to Python as a tuple?
I screwed up the question. I actually need a list, not a tuple, since it needs to be modifiable on the Python side. The rest of the question remains the same; except I should also mention that the array in question is 4128 chars long, not just 10. So copying it is not as trivial as the question first implies.
Ashish, if you really need it to be a `list` in python, then there is no way around it, you have to copy it. If you just need it to behave like a list, then that is possible. Just export your struct to python and implement methods such as __get__(), __set__(), __len()__, __eq__(), ... You may also read up on boost python indexing suite (optionally version 2) and see if that helps you to expose all these methods. If you write you class very much like std::vector, then the indexing suite can be of great help. Otherwise, just export those functions by hand. -Holger On Fri, Jul 26, 2013 at 11:16 PM, Ashish Sadanandan <ashish.sadanandan@gmail.com> wrote:
Ashish Sadanandan <ashish.sadanandan <at> gmail.com> writes:
I have a struct that contains a C-style array data member. I'd like to have this struct exposed to Python, and this data member be accessible as a tuple in Python.
struct S { char arr[10]; };
So the question is, how can I expose that C-style array data member to Python as a tuple?
I screwed up the question. I actually need a list, not a tuple, since it needs to be modifiable on the Python side. The rest of the question remains the same; except I should also mention that the array in question is 4128 chars long, not just 10. So copying it is not as trivial as the question first implies.
_______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Holger Brandsmeier <brandsmeier <at> gmx.de> writes:
Ashish,
if you really need it to be a `list` in python, then there is no way around it, you have to copy it. If you just need it to behave like a list, then that is possible. Just export your struct to python and implement methods such as __get__(), __set__(), __len()__, __eq__(), ...
You may also read up on boost python indexing suite (optionally version 2) and see if that helps you to expose all these methods. If you write you class very much like std::vector, then the indexing suite can be of great help. Otherwise, just export those functions by hand.
-Holger
Holger, Thanks for the response. I ended up doing what you suggested. Created an array_ref class that presents a non-owning view of an array; this has all the member functions that vector does, except for the ones that mutate the size of the container. The getter for the char array member wraps it in an array_ref, and then another class, array_indexing_suite, copied from Boost's vector_indexing_suite takes care of the rest of the interop. Thanks again, Ashish.
participants (2)
-
Ashish Sadanandan -
Holger Brandsmeier