[C++-sig] Exporting references into python

David Abrahams dave at boost-consulting.com
Mon Mar 3 00:02:19 CET 2003


Nicholas Francis <nich at users.sourceforge.net> writes:

> 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 forgot that objects are passed by-value to python functions by
default unless you use boost::ref(...).

  #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(boost::ref(x));
  }

  struct InputManager {};
  InputManager x;

  object get_in_mgr()
  {
      return get_object_reference(x);
  }

  BOOST_PYTHON_MODULE_INIT(test_ext)
  {
      class_<InputManager, boost::noncopyable>("InputManager");
      def("get_in_mgr", get_in_mgr);
  }

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com





More information about the Cplusplus-sig mailing list