[C++-sig] Returning values to Python in C++ reference arguments

Jason Addison jraddison at gmail.com
Sat May 23 18:05:31 CEST 2015


How can results be returned in function arguments?

I've include my example C++ extension and Python code below.

I've tried, what I think, are some obvious approaches (Python objects,
ctypes), though none have worked.

It seems like this should be doable.

If the python code owns, say, a c_int, I would thing it is mostly safe
to pass it to c++ to be modified.

This seems like it should be a common question, though I can't find it
being explicitly addressed in the documentation

All of the call policy stuff seems to only apply to the function result.

Can the policy stuff be applied to the function arguments?

If so, how would that work with my example?

Thanks,
Jason


my_module.cpp
>>>>
/*
clang++ -c -I/usr/include/python2.7 my_module.cpp
clang++ -dynamiclib -o my_module.so -lboost_python -lpython2.7
my_module.o
 */

#include <boost/python.hpp>

struct Foo {
    void bar(int &a, double &b) {
        a = 12;
        b = 6.2832;
    }
};

using namespace boost::python;

BOOST_PYTHON_MODULE(my_module)
{
    class_<Foo>("Foo", init<>())
        .def("bar", &Foo::bar)
    ;
}
<<<<


byref.py
>>>>
from ctypes import *
import my_module

f = my_module.Foo()

a = 0
b = 0.

# py objects
'''
f.bar(a, b)

Traceback (most recent call last):
  File "byref.py", line 8, in <module>
    f.bar(a, b)
Boost.Python.ArgumentError: Python argument types in
    Foo.bar(Foo, int, float)
did not match C++ signature:
    bar(Foo {lvalue}, int {lvalue}, double {lvalue})
'''

x = c_int(0)
y = c_double(0)

# as is
'''
f.bar(x, y)

Traceback (most recent call last):
  File "byref.py", line 25, in <module>
    f.bar(x, y)
Boost.Python.ArgumentError: Python argument types in
    Foo.bar(Foo, c_int, c_double)
did not match C++ signature:
    bar(Foo {lvalue}, int {lvalue}, double {lvalue})
'''

# ctype.byref
'''
f.bar(byref(x), byref(y))

Traceback (most recent call last):
  File "byref.py", line 36, in <module>
    f.bar(byref(x), byref(y))
Boost.Python.ArgumentError: Python argument types in
    Foo.bar(Foo, CArgObject, CArgObject)
did not match C++ signature:
    bar(Foo {lvalue}, int {lvalue}, double {lvalue})
'''

# ctype.pointer
'''
f.bar(pointer(x), pointer(y))

Traceback (most recent call last):
  File "byref.py", line 48, in <module>
    f.bar(pointer(x), pointer(y))
Boost.Python.ArgumentError: Python argument types in
    Foo.bar(Foo, LP_c_int, LP_c_double)
did not match C++ signature:
    bar(Foo {lvalue}, int {lvalue}, double {lvalue})
'''
<<<<


More information about the Cplusplus-sig mailing list