[C++-sig] custom r-value converters
Nathan Stewart
swarfrat at gmail.com
Fri Apr 2 06:51:39 CEST 2010
On Mon, Mar 29, 2010 at 4:31 PM, Roman Yakovenko
<roman.yakovenko at gmail.com>wrote:
> May be I am missing something, but (py++) variable_t class doesn't
> have return_by_value property.
>
> Indeed it doesn't. I was having trouble figuring out how to create a
return_by_value property to pass to the make functions.
>I am not sure. What py++ version do you use
> Can you post small and complete example, of what you are trying to do?
I didn't post an example because it's essentially 'How to Wrap a Custom
String' from the boost.python FAQ in py++.
Here's an example - I'm using py++ 1.0 and trying to wrap the following:
class CustomString
{
operator=(...)
string& val;
};
struct TypeOne
{
CustomString name;
};
struct TypeTwo
{
CustomString label;
}
In my py++ script, I create the CustomString_to_pystring and
CustomString_from_pystring structs as in the boost.python docs, and register
the converter.
Where I'm getting a bit confused, is do I need to let py++ wrap the
CustomString class, or does the rvalue converter replace that? I got around
the original property question by having my py++ script iterate through my
TypeN structs and if the type matches CustomString then I do a
property.exlude() and add the code using struct.add_registration_code() for
that property. At least that generates registration code like this:
bp::class_<TypeOne>("TypeOne")
.add_property("name",
make_getter(&TypeOne::name,
bp::return_by_value_policy<bp::return_by_value>()),
make_setter(&TypeOne::name,
bp::return_by_value_policy<bp::return_by_value>()))
Back to the question of wrapping CustomString though, if I exclude it
(thinking that exposing it was somehow messing with the rvalue conversion
stuff), it just segfaults. If I assign to my CustomString, it behaves as a
python string after that point. But until it has been assigned, it shows up
as <module.my.CustomString object at 0xF00...>.
My converters look like this:
struct CustomString_to_python_str
{
static PyObject* convert(CustomString const& s)
{
return
boost::python::incref(boost::python::object(const_cast<CustomString&>(s)).ptr());
}
};
struct CustomString_from_python_str
{
CustomString_from_python_str()
{
boost::python::converter::registry::push_back(
&convertible,
&construct,
boost::python::type_id<CustomString>());
}
static void* convertible(PyObject* obj_ptr)
{
if (!PyString_Check(obj_ptr)) return 0;
return obj_ptr;
}
static void construct(PyObject* obj_ptr,
boost::python::converter::rvalue_from_python_stage1_data* data)
{
const char* value = PyString_AsString(obj_ptr);
if (value == 0) boost::python::throw_error_already_set();
void* storage =
((boost::python::converter::rvalue_from_python_storage<CustomString>*)
data)->storage.bytes;
new (storage) CustomStringvalue);
data->convertible = storage;
}
}; // struct CustomString_from_python_str
And of course in the module init code, they're installed like so:
boost::python::to_python_converter<CustomString,
CustomString_to_python_str>();
CustomString_from_python_str();
The property getters & setters don't seem to be helpful or necessary - I
think now this might just be a default ctor initialization issue, but
providing initialization of the C++ class doesn't seem to work - it looks
like my converter is suspect.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20100402/4aa7ae68/attachment-0001.html>
More information about the Cplusplus-sig
mailing list