使用boost.python </double>公开std :: vector <double>

时间:2009-12-20 21:31:21

标签: c++ python boost-python

我编写了一些生成std :: vector的C ++代码。

我还有一个操作一些数据的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> >());
}

这似乎有效,但据我了解,它只为我的python脚本提供了一个类“PyVec”,但不提供我需要的数据。我错了吗?

我也看到其他人使用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
  4. 哪种方法最容易上手?我似乎没有采取任何办法。

    以下是我看过的更多链接: from the boost website from the python website another mailing list thread

    更新:

    这适用于将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:否to_python(按值)   转换器找到C ++类型:   std :: vector&gt;

    所以,显然我需要告诉python如何处理std :: vector。我认为这段代码可以帮助解决这个问题。

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

    但是由于std :: vector很常见,所以必须有一种定义的方法来做到这一点......对吗?

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:2)

我不确定我是否理解正确。导出可以保存std::vector<double>的类“PyVec”后,可以导出任何以向量作为输入或返回类型的c ++函数。所以你当然可以在c ++中填充你的vector并使用接口类型“PyVec”在Python中访问这些数据。