[C++-sig] String param from py to c++ by reference?

François Duranleau duranlef at iro.umontreal.ca
Fri Aug 3 17:26:27 CEST 2007


On Fri, 3 Aug 2007, Håkon Groven wrote:

> I have a c++ function that is defined like this:
> bool set_version(std::string &version); //pass by reference
>
> The wrapper def:
> .def("set_version", &survey_result::set_version)
>
> Python code:
> b = result.set_version('jalla')
>
> This does not work, and I get the following error:
>
> Caught Boost.Python.ArgumentError: Python argument types in
>    survey_result.set_version(survey_result, str)
> did not match C++ signature:
>    set_version(survey_result {lvalue}, std::string {lvalue})
>
> This works fine if I change the c++ code:
> bool set_version(std::string version); //pass by value
>
> Is it possible to make this work by reference instead of by value?

Your set_version function, is it intended to set something in the object 
or to modify the parameter? According to your usage example in Python, it 
seems like the former case. Then all you need to do is to pass the string 
by const reference, e.g.

   bool set_version( const std::string& version ) ;

If you can't modify that source code, then wrap it:

bool wrap_set_version( const survey_result& sr , const std::string& v )
{
     return sr.set_version( const_cast< std::string& >( v ) ) ;
}

and then:

//...
.def( "set_version" , & wrap_set_version )
//...

In the latter case, you will need a different interface on the Python 
side, because AFAIK, Python's strings are not mutable. You could do:

boost::python::tuple wrap_set_version( survey_result& sr ,
                                        const std::string& v )
{
     // it could be done more efficiently by taking a boost::python::str
     // argument instead of const std::string& and then extracting the
     // string in `version' below
     std::string version = v ;
     bool b = sr.set_version( version ) ;
     return boost::python::make_tuple( version , b ) ;
}

and then use .def(...) as above, and in Python:

v , b = result.set_version( 'jalla' )

Now v contains your modified string and b the boolean value.

-- 
François Duranleau
LIGUM, Université de Montréal


More information about the Cplusplus-sig mailing list