Ravi wrote:
[snip]

In order to use a function object in place of a free function, one must specialize/overload
  boost::python::detail::get_signature
which, for some reason, does not account for function objects. Here's a very simple example that works:

[snip]

However, note that the overload of get_signature precedes the inclusion of the boost.python headers, which is extremely inconvenient. However, if the headers are moved to their proper location as in the following,

[snip]

Why is the overloaded get_signature not picked up when it is declared *after* the inclusion of the headers?


I'm not sure why it isn't picked up. I've been working in this area, replacing most of detail/caller.hpp and detail/invoke.hpp with boost.fusion, seen here:

http://gitorious.org/~straszheim/boost/straszheim/blobs/python/boost/python/detail/caller.hpp

In the process, I overhauled get_signature to use boost::function_types, and to be a metafunction, not a function:

http://gitorious.org/~straszheim/boost/straszheim/blobs/python/boost/python/signature.hpp

The overall effect is a lot less preprocessor stuff to look around.

I have function objects (given a specialization of get_signature), and boost::function (only up to 3 arguments ATM) working,
here's the test (which passes):

/////////////////////////////////////

#include <boost/mpl/vector.hpp>
#include <boost/function.hpp>
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>

namespace mpl = boost::mpl;

struct X { int y; };

struct FnObject
{
  typedef int result_type;

  int operator()(X *x, int z) const
  {
    return z + x->y;
  }
};

int f1(X* x) { return x->y ; }
int f2(X* x, int i) { return x->y * i; }
int f3(X* x, int i, int j) { return x->y * i + j; }

namespace boost {
  namespace python {
    namespace detail {

      template<>
      struct get_signature<FnObject, X>
      {
        typedef mpl::vector<int, X*, int> type;
      };

    }
  }
}

using namespace boost::python;

BOOST_PYTHON_MODULE( function_objects_ext )
{
  FnObject fobj;
  boost::function<int(X*, int)> bf0(fobj);

  boost::function<int(X*)> bf1(f1);
  boost::function<int(X*, int)> bf2(f2);
  boost::function<int(X*, int, double)> bf3(f3);

  boost::python::class_<X>( "X" )
    .def( "fobj", fobj)
    .def( "bf0",  bf0)
    .def( "bf1",  bf1)
    .def( "bf2",  bf2)
    .def( "bf3",  bf3)
    .def_readwrite( "y", &X::y )
    ;
}

/////////////////////////////

>>> from function_objects_ext import *
>>> x = X()
>>> x.y = 13
>>> x.fobj(12)
25
>>> x.bf1()
13
>>> x.bf2(2)
26
>>> x.bf3(2, -27)
-1

/////////////////////////////

I'm fairly new to the internals of boost.python, and only just now got this working... Do you see problems with this, specifically the conversion of get_signature from function to metafunction?

-t


_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to