2017-05-04 36 views
0

私はPythonでPythonに関数を呼び出すC++にPythonを埋め込みました。私のPythonコードは次のとおりです。Boost Python PythonのC++プログラムへの戻り値

def predict(window, g_slope, g_compliance): 
    ps = model.predict_on_batch(
     x=np.asarray([window]) 
    ) 

    p_slopes = ps[0] 
    p_compliances = ps[1] 
    p_slopes = np.reshape(p_slopes, (np.shape(p_slopes)[1],)) 
    p_compliances = np.reshape(p_compliances, (np.shape(p_compliances)[1],)) 
    p_slope = p_slopes[-1] 
    p_compliance = p_compliances[-1] 

    n_slope = standardize_data(g_slope, means['GROUND_SLOPE'], variances['GROUND_SLOPE']) 
    n_compliance = standardize_data(g_compliance, means['GROUND_STIFFNESS'], variances['GROUND_STIFFNESS']) 

    #print('p_compliance: {0}, n_compliance: {1}, p_slope: {2}, n_slope: {3} '.format(str(p_compliance), str(n_compliance), str(n_slope), str(p_slope))) 

    return(p_slope, n_slope, p_compliance, n_compliance) 

私のC++プログラムで受け取りたいタプルを返します。 私のC++プログラムは次のように関数を呼び出します。

void ContactLearningApp::PythonWorkerThread() { 

    bp::object f = m_interface.attr("predict_on_data"); 

    printf("Start Python thread. \n"); 

    while (true) { 
     //printf("Inside while loop and waiting. \n"); 
     std::unique_lock<std::mutex> ul(m_mutex); 
     while (m_data.size() <= 0) { 
      m_NotEmptyCV.wait(ul); 
     } 
     Data dat = m_data.back(); 
     m_data.pop_back(); 

     ul.unlock(); 

     m_pydata_ptr py_ptr(new PyData); 

     py_ptr->InitWithData(dat); 
     try { 
      bp::tuple results = bp::extract<bp::tuple>(f(bp::ptr(py_ptr.get()))); 
      printf("p_slope: %f, n_slope: %f, p_compliance: %f, n_compliance %f \n", results[0], results[1], results[2], results[3]); 
     } 
     catch (const bp::error_already_set &import) { 
      // Parse and output the exception 
      std::string perror_str = parse_python_exception(); 
      std::cout << "Error in Python: " << perror_str << std::endl; 
     } 
    } 

} 

私は、Pythonから返されるタプルを抽出しようとしているが、私は次のようなエラーメッセージが出ます:

Expecting an object of type tuple; got an object of type NoneType instead. 

を、私はそれがないことを知っています私はタプル内の各値に正しくアクセスすることができません。タプルを抽出する正しい方法は何ですか?

答えて

0

boost::python::objectoperator[]をサポートしています。インデックス(リスト、タプルなど)の要素にアクセスできます。

bp::object func = bp::import("my_module").attr("my_func"); 
bp::object foo = func(); 
bp::object bar = foo[0]; 

を返されたPythonオブジェクトは、インデックスアクセスによってサポートされていない場合は、例外は次のようになります。これは、あなたが直接その要素にアクセスすることができ、tupleにあなたの関数から返さobjectをキャストする必要がないことを意味しますスローされる。インデックスによって抽出されたシーケンス要素をそれぞれのC++型にキャストする必要があるかもしれないことに注意してください。

通常、関数オブジェクトに引数を渡すことはできますが、そのままの状態でC++から ""ポインタを使用しないで "そのまま"です。 Boost.Pythonはほとんどの場合、必要な変換を行います。

+0

このようにオブジェクトから値を抽出しようとしました: 'bp :: extract (results [0])'しかし、 'NoneType object is subscriptable'エラーです。 – terminix00

+0

上記を無視してください。しかし、私はこのようにオブジェクトから値を抽出しようとしました: 'bp :: extract (results [0])'しかし、それは私のpythonスクリプトが印刷しているものとは逆の0.00000の値を与えます。 – terminix00

関連する問題