用 boost.python 暴露 std::vector<double>
Posted
技术标签:
【中文标题】用 boost.python 暴露 std::vector<double>【英文标题】:exposing std::vector<double> with boost.python 【发布时间】:2009-12-20 21:31:21 【问题描述】:我已经编写了一些生成 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,但发现它令人困惑。
我能想到几种方法
-
向
boost::python::exec_file
方法传递一些东西
使用boost_indexing_suite_ext
使用boost::shared_ptr
哪种方法最容易上手?我似乎没有明确的方法。
以下是我查看的更多链接: 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: No to_python (by-value) 找到 C++ 类型的转换器: 标准::向量>
所以,显然我需要告诉 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 很常见,所以必须有一个明确的方法来做到这一点......对吧?
【问题讨论】:
【参考方案1】:以下代码适用于我(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;
【讨论】:
有没有更面向对象的方法呢?而不是传递一个 python 字符串来执行.. 将向量转换为 sum 可以处理的类型并创建一个对象 sum = main_module("sum");... ?【参考方案2】:我不确定我是否理解正确。在导出可以保存std::vector<double>
的类“PyVec”后,您可以导出任何以向量作为输入或返回类型的 c++ 函数。所以当然你可以在 c++ 中填充你的向量,并在 Python 中使用接口类型“PyVec”访问这些数据。
【讨论】:
是的,但是如何在我的 Python 脚本中填充向量? 索引套件定义了__setitem__
和__getitem__
等,因此在python 中您可以使用下标运算符[] 填充向量。你看到 boost::python 索引套件的向量示例了吗? boost.org/doc/libs/1_41_0/libs/python/test/…
我不太了解...我认为这将有助于我最了解一些与我想做的事情类似的来源。
他可能的意思是您还应该查看.cpp
文件(替换链接中的.py
扩展名)以获取完整示例...以上是关于用 boost.python 暴露 std::vector<double>的主要内容,如果未能解决你的问题,请参考以下文章
删除由 boost::python 暴露的 std::vector 中的一个指针