2012-10-22 48 views
4

我需要將一個numpy數組傳遞給一個來自C++的python函數。 代碼如下。 Python端:使用boost python傳遞一個numpy數組FROM C++

import numpy as np 
import convert as cv 

def f(x): 
    x[0] = 5. 
    return len(x) 

if __name__ == '__main__': 
    y = np.array([1., 2., 3., 4.]) 
    x = cv.func_n(f, y) 
    print x 

的C++側:

#include <iostream> 
#include <boost/python.hpp> 

using namespace boost::python; 
double func_n(PyObject* f, numeric::array &x) 
{ 
    std::cerr << "Inside func_n\n"; 
    return boost::python::call<double>(f, boost::ref(x)); 
} 

BOOST_PYTHON_MODULE(convert) 
{ 
    numeric::array::set_module_and_type("numpy", "ndarray"); 

    def("func_n", &func_n); 

} 

什麼C++代碼是應該做的是採取一個python functopn和numpy的數組作爲兩個參數,然後再通過numpy的陣列到python函數。 我得到的錯誤是:

Traceback (most recent call last): 
    File "mm.py", line 11, in <module> 
    x = cv.func_n(f, y) 
TypeError: No Python class registered for C++ class class boost::python::numeric::array 

爲什麼?我是否需要在解釋器的遞歸調用過程中註冊模塊,如果是這樣,怎麼辦?

+0

繼續:使用return boost :: python :: call (f,x);而不是返回boost :: python :: call (f,boost :: ref(x));幫助和代碼工作正常。 boost :: ref(x)是做什麼的?我認爲boost :: python :: call複製了參數。原來它不是。哪裏可以澄清? – user1666241

回答

0

boost::ref(x)返回一個boost::reference_wrapper<T>,它允許您傳遞對按值函數的引用。

boost::python::call docs顯示參數的處理方式因其類型而異。如果參數是boost::reference_wrapper<T>,它實際上將對x的引用傳遞給Python。

因此,在上面的代碼中,您將對numeric :: array的引用傳遞給Python。你從Python調用的函數也接受一個引用。現在我不確定這一點,但我懷疑,因爲你實際上從來沒有真正在Python/C++之間傳遞數值::數組,所以boost :: python決定不包裝它或創建轉換器(因爲你是真的只是傳遞地址)。這可能是爲什麼你看不到爲numeric :: array類型註冊的Python類。