4

我编写了一些生成 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”,而不是我需要的数据。我错了吗?

我还看到其他一些人在 python 邮件列表中使用 boost::shared_ptr

我也找到了这个例子,但发现它令人困惑。

我能想到几种方法

  1. 传递一些东西给boost::python::exec_file方法
  2. 使用boost_indexing_suite_ext
  3. 英格boost::shared_ptr

哪种方法最容易上手?对我来说,没有一种方法很清楚。

以下是我查看的更多链接: 来自python 网站的 boost网站 另一个邮件列表线程

更新:

这适用于将一个传递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 >

所以,显然我需要告诉 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 很常见,所以必须有一个明确的方法来做到这一点……对吧?

4

2 回答 2

12

以下代码适用于我(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;
}
于 2010-01-11T20:55:54.230 回答
3

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

于 2009-12-21T09:08:40.537 回答