[C++-sig] [boost.python] char arrays in structs

Markus Schöpflin markus.schoepflin at comsoft.de
Mon Jul 4 17:42:29 CEST 2005


Ralf W. Grosse-Kunstleve wrote:

> --- Markus Schöpflin <markus.schoepflin at comsoft.de> wrote:

>>Using gcc-3.4.3 and boost.python 1.32.0. Full example:
>>
>>---%<---
>>#include <boost/python/module.hpp>
>>#include <boost/python/class.hpp>
>>
>>typedef char bar_t[4];

> Could you make it a boost::array<char, 4>?

Not really, because in reality it's an external fixed API.

>>struct foo
>>{
>>   bar_t bar;
>>   foo() {
>>     bar[0] = 'b'; bar[1] = 'a';
>>     bar[2] = 'r'; bar[3] = 0;
>>   }
>>};
>>
>>BOOST_PYTHON_MODULE(test)
>>{
>>   using namespace boost::python;
>>
>>   class_<foo>("foo")
>>     .def_readonly("bar", &foo::bar)
>>     ;
>>}
>>--->%---
>>
>>The compiles and links ok, but when using it from python I get the 
>>following error:
>>
>>Python 2.3 (#1, Jul 30 2003, 14:14:00)
>>[GCC 3.3 20030226 (prerelease) (SuSE Linux)] on linux2
>>Type "help", "copyright", "credits" or "license" for more information.
>> >>> from test import *
>> >>> print foo().bar
>>Traceback (most recent call last):
>>   File "<stdin>", line 1, in ?
>>TypeError: No to_python (by-value) converter found for C++ type: char [4]
>>
>>So I went ahead and added a custom converter for bar_t like so:
>>
>>struct bar_t_to_python_str
>>{
>>   static PyObject* convert(bar_t const &s)
> 
> 
> Here bar_t is equivalent to a plain char*. The size information is lost. This
> due to the C heritage.

Duh, I keep forgetting about that. But this makes me wondering why the 
custom converter indeed does the trick in my example.

> 
> 
>>   {
>>     return boost::python::incref(boost::python::object(s).ptr());
>>   }
>>};
>>
>>and in BOOST_PYTHON_MODULE(test):
>>
>>   to_python_converter<bar_t, bar_t_to_python_str>();
>>
>>Is it to be expected that I do need a custom type converter for this? Or do 
>>I miss something?

> You'd need a custom converter for boost::array<char, 4> if that is an option.
> The converter would also do the from_python conversion.
> 
> If the C++ interface is fixed, you'd have to work with thin wrappers. As long
> as you stay exclusively within the framework of C++, as Boost.Python does, this
> is the only option.

You mean thin wrapper as follows?

struct wrap_foo : public foo
{
   char const *get_bar() { return bar; }
};

and then

class_<foo_derived>("foo")
   .def_property("bar", &foo_derived::get_bar)
   ;

> 
> Cheers,
>         Ralf

Thanks, Markus




More information about the Cplusplus-sig mailing list