[C++-sig] Re: boost.python answer - thanks!

David Abrahams dave at boost-consulting.com
Tue Feb 25 06:45:21 CET 2003


"mghiggins <mghiggins at yahoo.com>" <mghiggins at yahoo.com> writes:

> Thanks, that helped a lot!

As I asked you before, please post your Boost.Python questions to the
C++-sig.

> Another perhaps more basic question: how do I pass a python function
> object to a C++ method and use it internally? e.g., if I have a class
>
> class Passer
> {
>  public:
>    Passer() {};
>    void setx( dict x ) { this->m_x = x; };
>    void setf( object f ) { this->m_f = f; };
>    double val();
>    double xval() { return extract<double>( m_x['v'] ); };
>
>  private:
>    dict   m_x;
>    object m_f;
> };
>
> double Passer::val()
> {
>    PyObject * f   = m_f.ptr();
>    PyObject * ret = PyEval_CallObject( f, m_x.ptr() );


why not just

     object ret = m_f(m_x);

??

>    double RetVal;
>    if( ret )
>       RetVal = 1;
>    else
>       RetVal = -1;
>
>    PyArg_Parse( ret, "(f)", &RetVal );
>    return RetVal;
> }

I don't know what your PyArg_Parse thing is supposed to be doing. I'm
not really sure what all of that 1/-1 stuff is about either.  Is
RetVal a tuple of one element?  Maybe you want:

 double Passer::val()
 {
     return m_f(m_x)[0];
 }

> The setx method seems to work fine with a dictionary like {'v':4} and
> the xval method returns its 'v' element properly.
>
> But the setf method doesn't seem to work correctly... when I call
> val() from python after setting on a function, PyObject * ret comes
> back NULL (which I learn from getting RetVal == -1 as a return value).

That might just mean that f raised a Python exception.  You're
masking the problem by returning -1 instead of using the Boost.Python
facilities which propagate the Python exception through your C++ code
and back to Python.

> I'm sure I'm doing something dumb by making the type of setf's arg be
> "object" rather than something specifying a function, but I don't know
> what. :) Anything obvious I'm missing here?

The only dumb-ish thing is using the raw Python 'C' API instead of
what Boost.Python gives you.  Try the simple approach I outlined
above; it might be revealing.

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





More information about the Cplusplus-sig mailing list