[C++-sig] Conversion from python objects to c++ objects for argument passing

Nicodemus nicodemus at globalite.com.br
Fri Nov 29 16:22:16 CET 2002


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.






More information about the Cplusplus-sig mailing list