2009-12-20 82 views
4

我寫了一些生成std :: vector的C++代碼。暴露std :: vector <double>與boost.python

我也有一個Python腳本來操縱一些數據,現在我聲明像這樣(下面)。

import numpy 
x = numpy.random.randn(1000) 
y = numpy.random.randn(1000) 

我可以正常運行腳本。從我的C++代碼:

using namespace boost::python; 
    try{ 
      Py_Initialize(); 
      object main = import("__main__"); 
      object global(main.attr("__dict__")); 
      object result = exec_file("scatterPlot.py", global, global); 
      Py_Finalize(); 
    } 
    catch(error_already_set){ 
      PyErr_Print(); 
    } 

    return; 

我不知道如何讓我的C++數據到python。我有很多,但似乎沒有什麼明確的。

我有我的C++

BOOST_PYTHON_MODULE(vector_indexing_suite_ext){ 
     boost::python::class_<std::vector<double> >("PyVec") 
     .def(boost::python::vector_indexing_suite<std::vector<double> >()); 
} 

這似乎是工作,但據我所知,它只是提供了一個類「PyVec」我的Python腳本,但我並不需要的數據。我錯了嗎?

我也看到一些其他人使用boost::shared_ptr in a python mailing list

我還發現this example,但發現它令人困惑。

我能想到的幾種方法

  1. 傳遞一些東西到boost::python::exec_file方法
  2. 使用boost_indexing_suite_ext
  3. Uinsg boost::shared_ptr

哪種方法是最容易得到持續?沒有辦法似乎對我很清楚。

這裏有一些更多的鏈接,我看了看: from the boost website from the python website another mailing list thread

UPDATE:

這適用於傳遞一個int我的Python代碼像下面

int main(){ 
     int five_squared=0; 
     int a =3; 
     try { 
       Py_Initialize(); 
       object main_module = import("__main__"); 
       object main_namespace = main_module.attr("__dict__"); 
       main_namespace["var"]=a; 
       object ignored = exec("result = 5 ** var", main_namespace); 
       five_squared = extract<int>(main_namespace["result"]); 
     } catch(error_already_set) { 
       PyErr_Print(); 
     } 
     std::cout << five_squared << std::endl; 
     return 0; 
} 

但我想通過一個載體,當我嘗試以類似的方式做到這一點,我得到了■錯誤

TypeError: No to_python (by-value) converter found for C++ type: std::vector >

所以,很顯然,我需要告訴蟒蛇如何處理的std ::向量。我認爲這個代碼可以幫助解決這個問題。

BOOST_PYTHON_MODULE(vector_indexing_suite_ext){ 
     boost::python::class_<std::vector<double> >("PyVec") 
     .def(boost::python::vector_indexing_suite<std::vector<double> >()); 
} 

但由於標準::向量是很常見的,必須有一個定義的方式來做到這一點,對吧?

回答

11

以下代碼適用於我(Python 2.6,Boost 1.39)。除了沒有BOOST_PYTHON_MODULE行本身(但矢量的class_定義)之外,這與您的代碼幾乎相同。只有在創建擴展模塊時才需要使用BOOST_PYTHON_MODULE

#include <iostream> 
#include <boost/python.hpp> 
#include <boost/python/suite/indexing/vector_indexing_suite.hpp> 
using namespace boost::python; 
using namespace std; 

int main() 
{ 
    vector<double> vec; 
    vec.push_back(1.2); 
    vec.push_back(3.4); 
    try { 
      Py_Initialize(); 

      boost::python::class_<std::vector<double> >("PyVec") 
      .def(boost::python::vector_indexing_suite<std::vector<double> >()); 

      object main_module = import("__main__"); 
      object globals = main_module.attr("__dict__"); 
      globals["var"]=vec; 
      object ignored = exec("result = sum(var)", globals, globals); 
      double result = extract<double>(globals["result"]); 
      std::cout << result << std::endl; 
    } catch(error_already_set) { 
      PyErr_Print(); 
    } 
    return 0; 
} 
+0

真棒,這真的有幫助 – devin 2010-01-12 06:05:45

+0

有沒有更多的面向對象的方式做到這一點?而不是傳遞一個python字符串來執行..一個la將矢量轉換爲sum可以處理並創建一個對象的類型sum = main_module(「sum」); ...? – SullX 2014-01-24 04:33:16

2

我不確定我是否理解正確。導出可以容納std::vector<double>的類「PyVec」之後,可以導出任何將vector作爲輸入或返回類型的C++函數。所以當然你可以在C++中填充你的向量,並使用接口類型「PyVec」在Python中訪問這些數據。

+0

是的但是,我將如何填充我的Python腳本中的向量? – devin 2009-12-22 07:36:25

+0

索引套件中定義了'__setitem__'和'__getitem__',所以在python中可以使用下標運算符[]來填充矢量。你看到了boost :: python索引套件的矢量示例嗎? http://www.boost.org/doc/libs/1_41_0/libs/python/test/vector_indexing_suite.py – rafak 2009-12-22 09:15:00

+0

我不太關注......我認爲這會最有助於我看到某些源代碼可以做類似的事情到我想要做的事情。 – devin 2010-01-08 03:30:06

相關問題