2009-12-20 87 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

相关问题