[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