2013-01-06 12 views
1

定義我的功能在Python陣列功能的陣列使用boost的Python在C++中,以獲得在Python

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

如何我可以通過使用升壓蟒蛇獲取負載在C函數指針++的數組在C++中訪問Func [0]到Func [N]。

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

我希望能夠調用

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

我嘗試以下2函子沒有成功

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; 

回答

2

你的問題是有點混亂對我說:你有函數指針的類型定義,但大家都知道,你會被調用函子。無論如何,你張貼不起作用,因爲你忘了導入數學代碼,嘗試用

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 
); 

那麼對於C++類型,您可能需要使用:

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

使用標準庫,它沒有咬:

typedef vector<CPP_Function> CPP_Function_vector; 

然後構建一個適配器,它從python對象構造CPP_Function對象。這幾天使用lambda函數是非常容易的。全部在一起:

#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; 

} 
+0

非常感謝,很好的回答! – Hesam