[C++-sig] Custom smart pointer and bp::wrapper

Paul Melis pyplusplus at assumetheposition.nl
Fri Jan 23 18:25:33 CET 2009


Paul Melis wrote:
> Roman Yakovenko wrote:
>   
>> 2009/1/17 Paul Melis <pyplusplus at assumetheposition.nl>:
>>   
>>     
>>> But when trying to run
>>>
>>> import doh
>>>
>>> class MyCallback(doh.Callback):
>>>    def execute(self, t):
>>>        print t
>>>        return 1
>>>
>>> m = MyCallback()
>>>
>>> t = doh.Thing()
>>> t.setCallback(m)
>>> t.update()
>>>
>>> i'm getting
>>>
>>> Traceback (most recent call last):
>>>  File "no_to_python_converter.py", line 12, in <module>
>>>    t.update()
>>> TypeError: No to_python (by-value) converter found for C++ type: Thing".
>>>
>>> And I fail to see why...
>>>     
>>>       
>> Mu guess: you need to use boost::python::register_ptr_to_python< Thin >();
>> ( http://www.boost.org/doc/libs/1_37_0/libs/python/doc/v2/register_ptr_to_python.html
>> )
>>   
>>     
> Well, that only seems to work on smart pointers, i.e. ref_ptr<Thing>.
> >From the docs:
> "|<boost/python/register_ptr_to_python.hpp>| supplies
> |register_ptr_to_python|, a function template which registers a
> conversion for smart pointers to Python"
>   
>> I have more or less complete example, which exports custom pointer
>> class and its usage to Python:
>> http://www.language-binding.net/pyplusplus/troubleshooting_guide/smart_ptrs/smart_ptrs.html
>>   
>>     
> Right, I did find it while trying to solve the above. But where our code
> differs is that my wrapper class (CallbackWrap) needs to pass a Thing*
> to Python and that's where it goes wrong. Your wrapper only returns an
> integer and doesn't pass any parameters to Python. I think that is the
> crucial difference here.
>   
Well, I seem to have found a solution. Instead of passing the pointer in
the call to the bp::override I wrap it back up in a ref_ptr, i.e.:

struct CallbackWrap : Callback, bp::wrapper<Callback>
{
    void execute(Thing* t)
    {
        if (bp::override ovr = this->get_override("execute"))
	{
	    ref_ptr<Thing> t_ref = t;
            ovr(t_ref);
	}
        else
            Callback::execute(t);
    }

    void default_execute(Thing* t) { this->Callback::execute(t); }
};


Paul


More information about the Cplusplus-sig mailing list