[C++-sig] Conversion from python objects to c++ objects for argument passing
Ralf W. Grosse-Kunstleve
rwgk at yahoo.com
Fri Nov 29 16:51:58 CET 2002
I don't know what is wrong with your code specifically, but you are using a
lvalue converter where you should be using a rvalue converter anyway. lvalue
converters are suitable only for accessing exisiting objects directly. You are
creating a new object, as a static object. This is not thread-safe and in all
likelihood has other drawbacks.
For more information please refer to the
How can I wrap functions which take C++ containers as arguments?
section at
http://www.boost.org/libs/python/doc/v2/faq.html
You may copy container_conversions.h to your own include tree. Include the file
in your extension module and then:
scitbx::boost_python::container_conversions::from_python_sequence<
std::vector<int>,
scitbx::boost_python::container_conversions::variable_capacity_policy>();
This should be all you need.
Ralf
--- Nicodemus <nicodemus at globalite.com.br> wrote:
> Hail!
>
> First, let me congratulate everyone involved in Boost.Python. The more
> you use it, the more you see how great the library is!
>
> I'm having a little problem though. I want that the following function:
>
> void PrintVec( const vector<int> &v )
> {
> vector<int>::const_iterator it = v.begin();
> stringstream ss;
> ss << "C++: [";
> while ( it != v.end() ){
> if ( it != v.begin() ){
> ss << ", ";
> }
> ss << *it;
> }
> ss << "]";
> cout << ss.str() << endl;
> }
>
> Be called like this from python:
>
> >>> PrintVec([1,2,3])
> C++: [1, 2, 3]
>
> To accomplish that, I've been using this lvalue converter:
>
> struct pylist_to_vector
> {
> static vector<int>& execute(PyObject& o)
> {
> static vector<int> v;
> v.clear();
> cout << "execute" << endl;
> if ( PyList_Check(&o) ){
> int size = PyList_Size(&o);
> cout << "size is " << size << endl;
> v.reserve( size );
> for( int i = 0; i < size; ++i ){
> PyObject* item = PyList_GetItem(&o, i);
> if ( PyInt_Check(item) ){
> int num = PyInt_AsLong(item);
> v.push_back( num );
> }
> else {
> cout << "Not a num at: " << i << endl;
> }
> }
> }
> cout << "returning..." << endl;
> return v;
> }
> };
>
> and in the module definition:
>
> BOOST_PYTHON_MODULE(test)
> {
> lvalue_from_pytype<pylist_to_vector, &PyList_Type>();
> def( "PrintVec", &PrintVec );
> }
>
> Everything links and compiles without a problem. But, when I execute:
> >>> PrintVec([1,2,3])
> execute
> size is 3
> returning...
>
> in python, it enters in an infinite loop and never stops. Debugging, I
> found out that it enters into my function, exits it, goes through
> boost.python, until it enters this code:
>
> /* file returning.hpp, line 114
> template<class P BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A)>
> static PyObject* call(
> R (*pf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A))
> , PyObject* args_
> , PyObject*, P const* policies)
> {
> // check that each of the arguments is convertible
> BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CHECK_CONVERSION, nil)
>
> if (!policies->precall(args_))
> return 0;
> (*pf)(BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CALL_ARGS, nil));
> return policies->postcall(args_, detail::none());
> }
>
> In the "return 0;" line, the processor hits 100% and the application blocks.
>
> So, what am I doing wrong? Is this the right way to accomplish what I
> want? I'm using Intel C++ 6 with STLport on windows.
>
> Thanks for any hints and comments,
> Bruno da Silva de Oliveira.
__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com
More information about the Cplusplus-sig
mailing list