[C++-sig] Exporting references into python

Nicholas Francis nich at users.sourceforge.net
Sun Mar 2 23:23:59 CET 2003


On søndag, mar 2, 2003, at 22:06 Europe/Copenhagen, David Abrahams  
wrote:

> Nicholas Francis <nich at users.sourceforge.net> writes:
>
>> A newbie question regarding boost::python.
>>
>> I need to make a templatized function that returns a
>> boost::python::object containing a reference to an object I already
>> have. Basically:
>>
>> template<class T>
>> object convertToPython (T &obj) {
>> 	return object (obj)
>> }
>>
>> All classes I pass through T are already wrapped (they are also not
>> copy-constructible). I tried with the code found at python.orgs wiki:
>>
>> template<class T> T& identity(T& x) { return x; }
>> template<class T> object get_object_reference (T& x) {
>> 	object f = make_function
>> 		(&identity<T>, return_value_policy<reference_existing_object());
>> 	return f(x);
>> }
>>
>> this code gave me a compile error (on CW 8.3, Mac OS X). Apparently CW
>> is convinced that the &identity<T> maps to void.
>
> Compiler bug.  It confounds VC6 and VC7 also.  The following works
> perfectly with cwpro8.3 and the others however:
>
>     #include <boost/python.hpp>
>
>     using namespace boost::python;
>
>     template<class T>
>     struct identity
>     {
>         static T& execute(T& x) { return x; }
>     };
>
>     template<class T> object get_object_reference (T& x)
>     {
>         object f = make_function
>             (&identity<T>::execute,  
> return_value_policy<reference_existing_object>());
>         return f(x);
>     }
>
>     struct InputManager {};
>     InputManager x;
>
>     object get_in_mgr()
>     {
>         return get_object_reference(x);
>     }
>
>     BOOST_PYTHON_MODULE_INIT(test_ext)
>     {
>         class_<InputManager>("InputManager");
>         def("get_in_mgr", get_in_mgr);
>     }

Thanks a lot for the help - I now got it to compile...

> Maybe you could update the Wiki?

I would be honored, but will wait untill all the problems are resolved  
(see below)

However, it seems to me that the real problem here is that InputManager  
(indeed, all T's I will be using) are not copy-constructible. If I try  
this with InputManager, which is declared as:

class_<InputManager, bases<GameManager>, boost::noncopyable>  
("InputManager")
...
;

It doesn't work. However, trying with a Vector3f (simple struct, 3  
floats) that IS copyable, it works as expected

>
>> I then tried to hardcode a type just to see if it worked at all:
>>
>> InputManager &identity (InputManager &x) { return x; }
>> object get_object_reference (InputManager &x) {
>> 	object f = make_function (
>> 		&identity, return_value_policy<reference_existing_object());
>> 	return f(x);
>> }
>>
>> This compiled, but gave me a typeerror at runtime: (No to_python
>> (by-value) converter found for c++ type: InputManager)
>
> Are you sure you know which Python code was causing that?

It happens when i do f(x). I tried splitting it up into:

object o = f(x)
printf ("Got here\n");
return o;

the Got here never was executed....

Here is a part of the stack trace when the exception was generated:  
(innermost calls last)

TestExtract()
_ZNK5boost6python3api16object_operatorsINS1_6objectEEclI12InputManagerEE 
NNS0_6detail9dependentIS3_T0_EE4typeERKT0_
_ZN5boost6python4callINS0_3api6objectE12InputManagerEENNS0_6detail10retu 
rnableIT_EE4typeEP7_objectRKT0_PNS_4typeIT_EE
boost::python::converter::arg_to_python<InputManager>::arg_to_python(Inp 
utManager&)
boost::python::converter::detail::value_arg_to_python<InputManager>::val 
ue_arg_to_python(InputManager&)
boost::python::converter::detail::arg_to_python_base::arg_to_python_base 
(const volatile void*, boost::python::converter::registration&)
boost::python::converter::registration::to_python(const volatile  
void*)const
boost::python::throw_error_already_set()

Cheers,
Nicholas Francis




More information about the Cplusplus-sig mailing list