[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