Take the tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have an array of functions in python

Func[0](x,y,z)
Func[1](x,y,z)
...
Func[N](x,y,z)

How I can load an array of function pointers in c++ by using boost-python get access to the Func[0] to Func[N] in c++.

typedef double (*CPP_Function)(double, double, double);
CPP_Function* Funcs; // Array of Function pointers

I want to be able to call

for(int i=0; i<N; i++)
   a += (*CPP_Function[i])(0,0,0)

I tried following for 2 functors with no success!

  Py_Initialize();

  bp::object main_module = bp::import("__main__");
  bp::object main_dict   = main_module.attr("__dict__");

  bp::exec(
    "def f1(x):\n"
    "  return  sin(x)*cos(x)\n"
    "def f2(x):\n"
    "  return  sin(x)*cos(x)\n"
    "f=[f1, f2]",
    main_dict
  );

  bp::object f = main_dict["f"];
  bp::object this_f = f[0];

  std::cout << bp::extract<double>(this_f(1.0)) << std::endl;
share|improve this question
add comment

1 Answer

up vote 2 down vote accepted

Your question is a bit confusing to me: you have a typedef for function pointers, but you are aware that you will be calling functors. Anyway, the code that you posted doesn't work because you forgot to import math, try with

  bp::exec(
    "from math import *\n"
    "def f1(x):\n"
    "  return  sin(x)*cos(x)\n"
    "def f2(x):\n"
    "  return  sin(x)*cos(x)\n"
    "f=[f1, f2]",
    main_dict
  );

Then for the c++ type, you might want to use:

  typedef std::function<double (double, double, double)> CPP_Function; // (a bad name)

Use the standard library, it doesn't bite:

  typedef vector< CPP_Function > CPP_Function_vector;

And then build an adaptor that constructs CPP_Function objects from python objects. It is extremely easy using lambda functions these days. All together:

#include <boost/python.hpp>

#include <functional>
#include <vector>

using namespace std;
namespace bp = boost::python;

typedef function<double(double, double, double)> CPP_Function;
typedef vector< CPP_Function > CPP_Function_vector; 

CPP_Function_vector convert_functions( bp::object const& functions ) 
{
    int l = bp::len( functions );
    CPP_Function_vector result;
    for (int i=0; i < l; i++ )
    {
        bp::object f = functions[i];
        result.push_back( [f]( double a, double b, double c)->double { return bp::extract<double>(f(a,b,c)); } );
    }
    return result;
}

int main( int argc, char* argv[] )
{

    Py_Initialize();

    bp::object main_module = bp::import("__main__");
    bp::object main_dict   = main_module.attr("__dict__");

    bp::exec(
        "from math import *\n"
        "def f1(x,y,z):\n"
        "  return  sin(x)*cos(y)*tan(z)\n"
        "def f2(x,y,z):\n"
        "  return  sin(x)*cos(z)\n"
        "f=[f1, f2]",
        main_dict
    );

    bp::object f = main_dict["f"];

    CPP_Function_vector function_vector = convert_functions( f );

    cout << function_vector[1](1.0, 0.2, 0.3) << endl;

    return 0;

}
share|improve this answer
 
Many thanks, great answer! –  Hesam Jan 6 '13 at 10:05
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.